perm filename SUPDUP.MID[NET,MRC]4 blob
sn#324536 filedate 1977-12-17 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00064 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00006 00002 Assembly options, etc.
C00009 00003 AC's, I/O channels, macros
C00011 00004 SUPDUP documentation
C00016 00005 BACKGROUND
C00021 00006 INITIALIZATION
C00027 00007 INITIALIZATION (continued)
C00029 00008 TTYOPT FUNCTION BITS
C00033 00009 TTYOPT FUNCTION BITS (continued)
C00036 00010 INPUT -- THE INTELLIGENT TERMINAL PROTOCOL
C00041 00011 INPUT -- THE INTELLIGENT TERMINAL PROTOCOL (continued)
C00045 00012 OUTPUT -- DISPLAY PROTOCOL (%TD CODES)
C00049 00013 OUTPUT -- DISPLAY PROTOCOL (%TD CODES) (continued)
C00052 00014 OUTPUT -- DISPLAY PROTOCOL (%TD CODES) (continued)
C00054 00015 STANFORD/ITS CHARACTER SET
C00057 00016 STANFORD/ITS CHARACTER SET (continued)
C00060 00017 ACKNOWLEDGEMENTS
C00062 00018 SUPDUP.MRC[UP,DOC]
C00066 00019 SUPDUP FEATURES:
C00070 00020 Everything nobody wanted to know about SUPDUP's internal mappings
C00073 00021 ITS TTY definitions
C00077 00022 ITS output buffer codes
C00079 00023 SAIL system definitions
C00083 00024 Data area
C00086 00025 IMP MTAPE command words
C00088 00026 Display crufties
C00091 00027 More display data stuff
C00094 00028 UUO server
C00098 00029 Interrupt server
C00100 00030 Startup, etc.
C00102 00031 Initial terminal setup
C00106 00032 Monitor command processor
C00108 00033 Get host name
C00111 00034 ICP ICP ICP
C00114 00035 Get socket number from logger
C00118 00036 Final pre-display initialization
C00120 00037 Slurp up and send terminal ID
C00122 00038 Now search for terminal
C00125 00039 Initialize screen
C00127 00040 TTY input service
C00130 00041 Output a character to the network buffer in the hairy way
C00135 00042 Network input service
C00139 00043 Check for other display stuff
C00141 00044 Subroutines for network input service
C00144 00045 Display hacking
C00147 00046 Display subroutines
C00150 00047 Non-insert/delete display subroutines
C00154 00048 More display subroutines
C00156 00049 Line insert
C00158 00050 Line delete
C00160 00051 Character insert
C00163 00052 Character delete
C00166 00053 Display update subroutines
C00171 00054 More display updating stuff
C00174 00055 DM display routines
C00179 00056 SUPDUP commands
C00181 00057 Display only commands
C00184 00058 Esoteric character mappings (all magical)
C00187 00059 Magic DDT command, subroutines, etc.
C00189 00060 SUPDUP help text
C00191 00061 Screen record crock
C00194 00062 Network error analysis
C00196 00063 More network error reporting
C00199 00064 Random routines, literals, etc.
C00202 ENDMK
C⊗;
subttl Assembly options, etc.
title SUPDUP
; Mark Crispin, SU-AI, November 1977
; This is the SAIL implementation of the ITS SUPDUP program, which is used
; for display communication across ITS systems. The protocol is described
; in RFC 734, NIC 41953.
.nstgw ; no storage words allowed
if2,[ ; Second time through just print switch settings
swprint \pdllen,words of PDL storage.
swprint \<pgmbeg-corbeg>,words impure storage.
swprint \<sdpff-pgmbeg>,words pure storage.
swprint \dmbufl,words DM buffer storage.
swprint \icpskt,is the ICP socket.
radix 10. ; print these in decimal
swprint \nlines,maximum lines in screen matrix.
swprint \linel,maximum characters in screen matrix.
swprint \nlnglt,line(s) per glitch when scrolling.
swprint \nlnupd,minimum lines changed to cause full screen update.
swprint \clkspd,seconds between clock interrupts
radix 8. ; back to octal
.hkill icp,net,dsk ; so DDT doesn't confuse these
; with AC's on typeout
];if2
if1,[ ; First time through define all macros, symbols, etc.
; Canonical macro library
.insrt MACROS[1,MRC]
; Assembly switches
nd. icpskt==137 ; new SUPDUP ICP socket
nd. pdllen==50 ; length of pushdown stack
nd. dmbufl==200 ; words of DM buffer space
nd. nlines==40. ; maximum number of lines on screen
nd. linel==88. ; maximum number of characters
nd. nlnglt==1 ; number of lines to glitch when scrolling
nd. clkspd==3. ; three seconds of clock time
nd. nlnupd==3. ; number of lines that cause screen update
; instead of updating individual lines
nchars==<<<linel+5>/5>*5> ; # chars/line; must be a multiple of 5
subttl AC's, I/O channels, macros
; Accumulators
; I is an interrupt level AC and may not be used anywhere else. Things
; depend on the order of X, Y, Z, and A being consecutive. U and T are
; used at UUO level.
acdef. [x y z a b c i t u]
; I/O channels
; ICP is used for ICP'ing only, NET is the general network work channel,
; DSK is used for reading ROOMS[P,DOC] and for recording the screen.
acdef. [icp net dsk]
; Macros
; Print out switch settings
define swprint value,line/
printx/value line
/
termin
; Map character in ac to char2 if it contains char1 now
define mapit ac,char1,char2
caxn ac,char1
jrst [movx ac,char2
return]
termin
; Generate a Data Disc command
define ddcmd o1,d1,o2,d2,o3,d3
.byte 8.,8.,8.,3.,3.,3.,3.
d1 ? d2 ? d3 ? o1 ? o2 ? o3 ? 4
.byte
termin
; Send a DM command character
define dmcmd ch
move x,dmcnt
caxge x,10
call dmout
movx x,177
call dmchar
movx x,ch
call dmchar
termin
subttl SUPDUP documentation
COMMENT ⊗
NWG/RFC# 734 MRC 07-OCT-77 08:46 41953
SUPDUP Display Protocol
Network Working Group Mark Crispin
Request for Comments 734 SU-AI
NIC 41953 7 October 1977
SUPDUP Protocol
INTRODUCTION
This document describes the SUPDUP protocol, a highly efficient display
telnet protocol. It originally started as a private protocol between the
ITS systems at MIT to allow a user at any one of these systems to use one
of the others as a display. At the current writing, SUPDUP user programs
also exist for Data Disc and Datamedia displays at SU-AI and for
Datamedias at SRI-KL. The author is not aware of any SUPDUP servers other
than at the four MIT ITS sites.
The advantage of the SUPDUP protocol over an individual terminal's
protocol is that SUPDUP defines a "virtual" or "software" display terminal
that implements relevant cursor motion operations. The protocol is not
built on any particular display terminal but rather on the set of
functions common to all display terminals; hence it is completely device-
independent. In addition, the protocol also provides for terminals which
cannot handle certain operations, such as line or character insert/delete.
In fact, it is more than this. It provides for terminals which are
missing any set of features, all the way down to model 33 Teletypes.
The advantage over the TELNET protocol is that SUPDUP takes advantage of
the full capabilities of display terminals, although it also has the
ability to run printing terminals.
It is to be noted that SUPDUP operates independently from TELNET; it is
not an option to the TELNET protocol. In addition, certain assumptions
are made about the server and the user programs and their capabilities.
Specifically, it is assumed that the operating system on a server host
provides all the display-oriented features of ITS. However, a server may
elect not to do certain display operations available in SUPDUP; the SUPDUP
protocol is far-reaching enough so that the protocol allows terminals to
be handled as well as that host can handle terminals in general. Of
course, if a host does not support display terminals in any special way,
there is no point in bothering to implement a SUPDUP server since TELNET
will work just as well.
A more complete description of the display facilities of SUPDUP and ITS
can be found by FTP'ing the online file .INFO.;ITS TTY from ARPAnet host
MIT-AI (host 206 octal, 134. decimal). For more information, the mailing
address for SUPDUP is "(BUG SUPDUP) at MIT-AI". If your mail system won't
allow you to use parentheses, use Bug-SUPDUP@MIT-AI.
BACKGROUND
The SUPDUP protocol originated as the internal protocol used between parts
of ITS, and between ITS and "intelligent" terminals. Over the network, a
user host acts like an intelligent terminal programmed for ITS.
The way terminal output works in ITS is as follows: The user program
tells the system to do various operations, such as printing characters,
clearing the screen, moving the cursor, etc. These operations are formed
into 8-bit characters (using the %TD codes described below) and stored
into a buffer. At interrupt level, as the terminal demands output,
characters are removed from the buffer and translated into terminal
dependent codes. At this time padding and cursor motion optimization are
also done.
In some cases, the interrupt side does not run on the same machine as the
user program. SUPDUP terminals have their "interrupt side" running in the
user host. When SUPDUP is run between two ITS's, the SUPDUP user and
server programs and the network simply move characters from the buffer in
the server machine to the buffer in the user machine. The interrupt side
then runs on the user machine just as if the characters had been generated
locally.
Due to the highly interactive characteristics of both the SUPDUP protocol
and the ITS system, all transactions are strictly character at a time and
all echoing is remote. In addition, all padding and cursor control
optimization must be done by the user.
Because this is also the internals of ITS, the right to change it any time
if necessary to provide new features is reserved by MIT. In particular,
the initial negotiation is probably going to be changed to transmit
additional variables, and additional %TD codes may be added at any time.
User programs should ignore those they don't know about.
The following conventions are used in this document: function keys (ie,
keys which represent a "function" rather than a "graphic character") are
in upper case in square brackets. Prefix keys (ie, keys which generate no
character but rather are held down while typing another character to
modify that character) are in upper case in angle brackets. Hence
"<CONTROL><META>[LINE FEED]" refers to the character generated when both
the CONTROL and META keys are held down while a LINE FEED is typed. Case
should be noted; <CONTROL>A refers to a different character from
<CONTROL>a. Finally, all numbers which do not explicitly specify a base
(ie, octal or decimal) should be read as octal unless the number is
immediately followed by a period, in which case it is decimal.
INITIALIZATION
The SUPDUP server listens on socket 137 octal. ICP proceeds in the normal
way for establishing 8-bit connections. After the ICP is completed, the
user side sends several parameters to the server side in the form of
36.-bit words. Each word is sent through the 8-bit connection as six
6-bit bytes, most-significant first. Each byte is in the low-order 6 bits
of a character. The first word is the negative of the number of variables
to follow in the high order 18. bits (the low-order 18. bits are ignored),
followed by the values of the TCTYP, TTYOPT, TCMXV, TCMXH, and TTYROL
terminal descriptor variables (these are the names they are known by at
ITS sites). These variables are 36.-bit binary numbers and define the
terminal characteristics for the virtual terminal at the REMOTE host.
The count is for future compatability. If more variables need to be sent
in the future, the server should assume "reasonable" default values if the
user does not specify them. PDP-10 fans will recognize the format of the
count (ie, -count,,0) as being an AOBJN pointer. At the present writing
there are five variables hence this word should be -5,,0.
The TCTYP variable defines the terminal type. It MUST be 7 (%TNSFW). Any
other value is a violation of protocol.
The TTYOPT variable specifies what capabilities or options the user's
terminal has. A bit being true implies that the terminal has this option.
This variable also includes user options which the user may wish to alter
at his or her own descretion; these options are included since they may be
specified along with the terminal capabilities in the initial negotiation.
See below for the relevant TTYOPT bits.
The TCMXV variable specifies the screen height in number of lines.
The TCMXH variable specifies the line width in number of characters. This
value is one less than the screen width (ITS indicates line overflow by
outputting an exclamation point at the end of the display line before
moving to the next line). Note: the terminal must not do an automatic
CRLF when a character is printed in the rightmost column. If this is
unavoidable, the user SUPDUP must decrement the width it sends by one.
Note: Setting either the TCMXV or TCMXH dimension greater than 128. will
work, but will have some problems as coordinates are sometimes represented
in only 7 bits. The main problems occur in the SUPDUP protocol when
sending the cursor position after an output reset and in ITS user programs
using the display position codes ↑PH and ↑PV.
The TTYROL variable specifies the "glitch count" when scrolling. This is
the number of lines to scroll up when scrolling is required. If zero, the
terminal is not capable of scrolling. 1 is the usual value, but some
terminals glitch up by more than one line when they scroll.
Following the transmission of the terminal options by the user, the server
should respond with an ASCII greeting message, terminated with a %TDNOP
code (%TD codes are described below). All transmissions from the server
after the %TDNOP are either printing characters or virtual terminal
display codes.
INITIALIZATION (continued)
The user and the server now both communicate using the intelligent
terminal protocol (described below) from the user and %TD codes from the
server. The user has two commands in addition to these; they are escaped
by sending 300 (octal). If following the escape is a 301 (octal), the
server should attempt to log off the remote job (generally this is sent
immediately before the user disconnects, so this logout procedure should
be done regardless of the continuing integrity of the connection). If the
character following the escape is a 302 (octal), all ASCII characters
following up to a null (000 octal) are interpreted as "console location"
which the server can handle as it pleases. No carriage return or line
feed should be in the console location text. Normally this is saved away
to be displayed by the "who" command when other users ask where this user
is located.
TTYOPT FUNCTION BITS
The relevant TTYOPT bits for SUPDUP usage follow. The values are given in
octal, with the left and right 18-bit halves separated by ",," as in the
usual PDP-10 convention.
Bit name Value Meaning
%TOALT 200000,,0 characters 175 and 176 are converted to
altmode (033) on input.
%TOERS 40000,,0 this terminal is capable of selectively
erasing its screen. That is, it supports
the %TDEOL, the %TDDLF, and (optionally)
the %TDEOF operations. For terminals
which can only do single-character
erasing, see %TOOVR.
%TOMVB 10000,,0 this terminal is capable of backspacing
(ie, moving the cursor backwards).
%TOSAI 4000,,0 this terminal has the Stanford/ITS
extended ASCII graphics character set.
%TOOVR 1000,,0 this terminal is capable of overprinting;
if two characters are displayed in the
same position, they will both be visible,
rather than one replacing the other.
Lack of this capability but the capability
to backspace (see %TOMVB) implies that the
terminal can do single character erasing
by overstriking with a space. This allows
terminals without the %TOERS capability to
have display-style "rubout processing", as
this capability depends upon either %TOERS
or [%TOMVB and not %TOOVR].
%TOMVU 400,,0 this terminal is capable of moving the
cursor upwards.
%TOLWR 20,,0 this terminal's keyboard is capable of
generating lowercase characters; this bit
is mostly provided for programs which want
to know this information.
%TOFCI 10,,0 this terminal's keyboard is capable of
generating CONTROL and META characters as
described below.
%TOLID 2,,0 this terminal is capable of doing line
insert/delete operations, ie, it supports
%TDILP and %TDDLP.
%TOCID 1,,0 this terminal is capable of doing
character insert/delete operations, ie, it
supports %TDICP and %TDDCP.
TTYOPT FUNCTION BITS (continued)
Bit name Value Meaning
%TPCBS 0,,40 this terminal is using the "intelligent
terminal protocol".
THIS BIT MUST BE ON.
%TPORS 0,,10 the server should process output resets
instead of ignoring them.
IT IS HIGHLY RECOMMENDED THAT THIS BIT BE
ON; OTHERWISE THERE MAY BE LARGE DELAYS IN
ABORTING OUTPUT.
The following bits are user option bits. They may be set or not set at
the user's discretion. The bits that are labelled "normally on" are those
that are normally set on when a terminal is initialized (ie, by typing
[CALL] on a local terminal).
Bit name Value Meaning
%TOCLC 100000,,0 convert lower-case input to upper case.
Many terminals have a "shift lock" key
which makes this option useless.
NORMALLY OFF.
%TOSA1 2000,,0 characters 001-037 should be displayed
using the Stanford/ITS extended ASCII
graphics character set instead of uparrow
followed by 100+character.
NORMALLY OFF.
%TOMOR 200,,0 the system should provide "**MORE**"
processing when the cursor reaches the
bottom line of the screen. **MORE**
processing is described in ITS TTY.
NORMALLY ON.
%TOROL 100,,0 the terminal should scroll when attempting
output below the bottom line of the screen
instead of wrapping around to the top.
NORMALLY OFF.
INPUT -- THE INTELLIGENT TERMINAL PROTOCOL
Note: only the parts of the intelligent terminal protocol relevant to
SUPDUP are discussed here. For more information, read ITS TTY.
CHARACTER SETS
There are two character sets available for use with SUPDUP; the 7-bit
character set of standard ASCII, and the 12-bit character set of extended
ASCII. Extended ASCII has 5 high order or "bucky" bits on input and has
graphics for octal 000-037 and 177 (see the section entitled "Stanford/ITS
character set" for more details). The two character sets are identical on
output since the protocol specifies that the host should never send the
standard ASCII formatting characters (ie, TAB, LF, VT, FF, CR) as
formatting characters; the characters whose octal values are the same as
these formatting characters are never output unless the user job has these
characters enabled (setting %TOSAI and %TOSA1 generally does this).
Input differs dramatically between the 7-bit and 12-bit character sets.
In the 7-bit character set, all characters input whose value is 037 octal
or less are assumed to be (ASCII) control characters. In the 12-bit
character set, there are 5 "bucky" bits which may be attached to the
character. The two most important of these are CONTROL and META, which
form a 9-bit character set. TOP is used to distinguish between printing
graphics in the extended character set and ASCII controls. The other two
are reserved and should be ignored. Since both 7-bit and 12-bit terminals
are commonly in use, 0001, 0301, and 0341 are considered to be <CONTROL>A
on input by most programs, while 4001 is considered to be downwards arrow.
MAPPING BETWEEN CHARACTER SETS
Many programs and hosts do not process 12-bit input. In this case, 12-bit
input is folded down to 7-bit as follows: TOP and META are discarded. If
CONTROL is on, then if the 7-bit part of the character specifies a lower
case alphabetic it is converted to upper case; then if the 7-bit part is
between 077 and 137 the 100 bit is complemented or if the 7-bit part is
040 the 040 bit is subtracted (that's right, <CONTROL>? is converted to
[RUBOUT] and <CONTROL>[SPACE] is converted to [NULL]). In any case the
CONTROL bit is discarded, and the remainder is treated as a 7-bit ASCII
character. It should be noted that in this case downwards arrow is read
by the program as standard ASCII <CONTROL>A.
Servers which expect 12-bit input and are told to use the 7-bit character
set should do appropriate unfolding from the 7-bit character set to
12-bit. It is up to the individual server to decide upon the unfolding
scheme. On ITS, user programs that use the 12-bit character set generally
have an alternative method for 7-bit; this often takes the form of prefix
characters indicating that the next character should be "controllified" or
"metized", etc.
INPUT -- THE INTELLIGENT TERMINAL PROTOCOL (continued)
BUCKY BITS
Under normal circumstances, characters input from the keyboard are sent to
the foreign host as is. There are two exceptions; the first occurs when
an octal 034 character is to be sent; it must be quoted by being sent
twice, because 034 is used as an escape character for protocol commands.
The second exception occurs when %TOFCI is set and a character with
non-zero bucky bits is to be sent. In this case, the character, which is
in the 12-bit form:
Name Value Description
%TXTOP 4000 This character has the [TOP] key depressed.
%TXSFL 2000 Reserved, must be zero.
%TXSFT 1000 Reserved, must be zero.
%TXMTA 400 This character has the [META] key depressed.
%TXCTL 200 This character has the [CONTROL] key depressed.
%TXASC 177 The ASCII portion of the character
is sent as three bytes. The first byte is always 034 octal (that is why
034 must be quoted). The next byte contains the "bucky bits", ie, the
%TXTOP through %TXCTL bits, shifted over 7 bits (ie, %TXTOP becomes 20)
with the 100 bit on. The third byte contains the %TXASC part of the
character. Hence the character <CONTROL><META>[LINE FEED] is sent as 034
103 012.
OUTPUT RESETS
The intelligent terminal protocol also is involved when a network
interrupt (INR/INS) is received by the user program. The user program
should increment a count of received network interrupts when this happens.
It should not do any output, and if possible abort any output in progress,
if this count is greater than zero (NOTE: the program MUST allow for the
count to go less than zero).
Since the server no longer knows where the cursor is, it suspends all
output until the user informs it of the cursor position. This also gives
the server an idea of how much was thrown out in case it has to have some
of the aborted output displayed at a later time. The user program does
this when it receives a %TDORS from the server. When this happens it
should decrement the "number of received network interrupts" count
described in the previous paragraph and then send 034 followed by 020, the
vertical position, and the horizontal position of where the cursor
currently is located on the user's screen.
OUTPUT -- DISPLAY PROTOCOL (%TD CODES)
Display output is somewhat simpler. Codes less than 200 octal are
printing characters and are displayed on the terminal (see the section
describing the "Stanford/ITS character set"). Codes greater than or equal
to 200 (octal) are known as "%TD codes", so called since their names begin
with %TD. The %TD codes that are relevant to SUPDUP operation are listed
here. Any other code received should be ignored, although a bug report
might be sent to the server's maintainers. Note that the normal ASCII
formatting characters (011 - 015) do NOT have their formatting sense under
SUPDUP and should not occur at all unless the Stanford/ITS extended ASCII
character set is in use (ie, %TOSAI is set in the TTYOPT word).
For cursor positioning operations, the top left corner is (0,0), ie,
vertical position 0, horizontal position 0.
%TD code Value Meaning
%TDMOV 200 General cursor position code. Followed by
four bytes; the first two are the "old"
vertical and horizontal positions and may
be ignored. The next two are the new
vertical and horizontal positions. The
cursor should be moved to this position.
On printing consoles (non %TOMVU), the old
vertical position may differ from the true
vertical position; this can occur when
scrolling. In this case, the user program
should set its idea of the old vertical
position to what the %TDMOV says and then
proceed. Hence a %TDMOV with an old vpos
of 20. and a new vpos of 22. should always
move the "cursor" down two lines. This is
used to prevent the vertical position from
becoming infinite.
%TDMV1 201 An internal cursor motion code which
should not be seen; but if it is, it has
two argument bytes after it and should be
treated the same as %TDMV0.
%TDEOF 202 Erase to end of screen. This is an
optional function since many terminals do
not support this. If the terminal does
not support this function, it should be
treated the same as %TDEOL.
%TDEOF does an erase to end of line, then
erases all lines lower on the screen than
the cursor. The cursor does not move.
%TDEOL 203 Erase to end of line. This erases the
character position the cursor is at and
all positions to the right on the same
line. The cursor does not move.
OUTPUT -- DISPLAY PROTOCOL (%TD CODES) (continued)
%TD code Value Meaning
%TDDLF 204 Clear the character position the cursor is
on. The cursor does not move.
%TDCRL 207 If the cursor is not on the bottom line of
the screen, move cursor to the beginning
of the next line and clear that line. If
the cursor is at the bottom line, scroll
up.
%TDNOP 210 No-op; should be ignored.
%TDORS 214 Output reset. This code serves as a data
mark for aborting output much as IAC DM
does in the ordinary TELNET protocol.
%TDQOT 215 Quotes the following character. This is
used when sending 8-bit codes which are
not %TD codes, for instance when loading
programs into an intelligent terminal.
The following character should be passed
through intact to the terminal.
%TDFS 216 Non-destructive forward space. The cursor
moves right one position; this code will
not be sent at the end of a line.
%TDMV0 217 General cursor position code. Followed by
two bytes; the new vertical and horizontal
positions.
%TDCLR 220 Erase the screen. Home the cursor to the
top left hand corner of the screen.
%TDBEL 221 Generate an audio tone, bell, whatever.
%TDILP 223 Insert blank lines at the cursor; followed
by a byte containing a count of the number
of blank lines to insert. The cursor is
unmoved. The line the cursor is on and
all lines below it move down; lines moved
off the bottom of the screen are lost.
%TDDLP 224 Delete lines at the cursor; followed by a
count. The cursor is unmoved. The first
line deleted is the one the cursor is on.
Lines below those deleted move up. Newly-
created lines at the bottom of the screen
are blank.
OUTPUT -- DISPLAY PROTOCOL (%TD CODES) (continued)
%TD code Value Meaning
%TDICP 225 Insert blank character positions at the
cursor; followed by a count. The cursor
is unmoved. The character the cursor is
on and all characters to the right on the
current line move to the right; characters
moved off the end of the line are lost.
%TDDCP 226 Delete characters at the cursor; followed
by a count. The cursor is unmoved. The
first character deleted is the one the
cursor is on. Newly-created characters at
the end of the line are blank.
%TDBOW 227 Display black characters on white screen.
HIGHLY OPTIONAL.
%TDRST 230 Reset %TDBOW and such any future options.
STANFORD/ITS CHARACTER SET
This section describes the extended ASCII character set. It originated
with the character set developed at SAIL but was modified for 1968 ASCII.
This character set only applies to terminals with the %TOSAI and %TOFCI
bits set in its TTYOPT word. For non-%TOSAI terminals, the standard ASCII
printing characters are the only available output characters. For
non-%TOFCI terminals, the standard ASCII characters are the only available
input characters.
PRINTING CHARACTERS
The first table describes the printing characters. For output, the 7-bit
code is sent (terminal operations are performed by %TD codes). For input,
the characters with values 000-037 and 177 must have the %TXTOP bit on to
indicate the graphic is intended rather than a function or ASCII control.
Value Character
4000 centered dot
4001 downward arrow
4002 alpha
4003 beta
4004 logical AND
4005 logical NOT
4006 epsilon
4007 pi
4010 lambda
4011 gamma
4012 delta
4013 uparrow
4014 plus-minus
4015 circle-plus
4016 infinity
4017 partial delta
4020 proper subset (left horseshoe)
4021 proper superset (right horseshoe)
4022 intersection (up horseshoe)
4023 union (downward horseshoe)
4024 universal quantifer
4025 existential quantifier
4026 circle-X
4027 double arrow
4030 left arrow
4031 right arrow
4032 not-equal
4033 lozenge (diamond)
4034 less-than-or-equal
4035 greater-than-or-equal
4036 equivalence
4037 logical OR
0040 first standard ASCII character (space)
.. . . .
0176 last standard ASCII character (tilde)
4177 integral
STANFORD/ITS CHARACTER SET (continued)
FUNCTION KEYS AND SPECIAL CHARACTERS
In addition, the following special characters exist for input only. These
characters are function keys rather than printing characters; however,
some of these characters have some format effect or graphic which they
echo as; the host, not the SUPDUP program, handles any such mappings.
Value Character Usual echo Usual Function
0000 [NULL]
0010 [BACK SPACE] text formatting
0011 [TAB] text formatting
0012 [LINE FEED] text formatting
0013 [VT] text formatting
0014 [FORM] text formatting
0015 [RETURN] text formatting
0032 [CALL] uparrow-Z escape to system
0033 [ALTMODE] lozenge or $ special activation
0037 [BACK NEXT] uparrow-underscore monitor command prefix
0177 [RUBOUT] character delete
4101 [ESCAPE] local terminal command
4102 [BREAK] local subsystem escape
4103 [CLEAR]
4110 [HELP] requests a help message
BUCKY BITS
For all input characters, the following "bucky bits" may be added to the
character. Their interpretation depends entirely upon the host. <TOP> is
not listed here, as it has been considered part of the character in the
previous tables.
<CONTROL> is different from ASCII CTRL, however, many programs may request
the operating system to map such characters to the ASCII forms (with the
<TOP> bit off). In this case <META> is ignored.
Value Key
2000 Reserved
1000 Reserved
0400 <META>
0200 <CONTROL>
ACKNOWLEDGEMENTS
Richard M. Stallman (RMS@MIT-AI) and David A. Moon (Moon@MIT-MC) of the
MIT-AI and MIT-MC systems staff wrote the source documentation and the
wonderful ITS terminal support that made this protocol possible. It must
be emphasized that this is a functional protocol which has been in
operation for some years now.
In addition, Moon, Stallman, and Michael McMahon (MMcM@SRI-KL) provided
many helpful comments and corrections to this document.
For further reference, the sources for the known currently existing SUPDUP
user programs are available online as:
[MIT-AI] SYSENG;SUPDUP > for the ITS monitor,
[SU-AI] SUPDUP.MID[NET,MRC] for the SAIL monitor,
[SRI-KL] <MMcM>SD.FAI for the TOPS-20 monitor.
The source for the known currently existing SUPDUP server program is:
[MIT-AI] SYSENG;TELSER > for the ITS monitor.
These programs are written in the MIDAS and FAIL dialects of PDP-10
assembly language.
SUPDUP.MRC[UP,DOC]
SUPer-DUPer Display TELNET to ITS
Mark Crispin
INTRODUCTION:
SUPDUP is the SAIL implementation of the ITS SUPDUP program, which is used
for TELNETing between ITS sites. This program uses the internal ITS
display codes for highly efficient communication and full use of ITS
display programs over the ARPAnet. In addition, SUPDUP allows the user to
send the full ITS ASCII character set (which includes some very hairy
characters!) and maps both keyboard input and display output so that a
Stanford display (DD, III, or DM) appears as a funny kind of ITS display.
SUPDUP also runs on printing consoles; on these ↑↑ enters command mode.
When SUPDUP is run, it will prompt for the host name. Type one or two
characters to identify the name of the ITS system you wish to TELNET to
(ie, either "A", "D", "MC", and "ML"). SUPDUP will then establish a
connection with the specified ITS site, and after that you will
effectively be a display on ITS, with full bucky bit capability.
Some mappings in input and output are made due to the differences between
the SAIL and ITS ASCII character sets. Most of these mappings are
transparent to the user. The design philsophy behind the mappings was to
cause characters typed on the Stanford keyboard to be seen by ITS as the
character appears on the key tops, and for characters received from ITS to
be displayed as they would be at a console at MIT.
NOTE!!!:
One thing that I should mention: you MUST NOT do a :TCTYP on ITS that will
set your terminal type. SUPDUP's operation depends upon the terminal type
being SOFTWARE and things will not work correctly if it is set to anything
else. It is alright to set certain other TCTYP options such as SAIL
character set enable, however, in general you probably will not want to do
any TCTYP at all. SUPDUP sets the line length and page size to the
maximum possible on the screen.
SUPDUP FEATURES:
Visible OUTPUT MAPPINGS:
Caret is mapped to AND sign (∧) since there is no code in the SAIL
character set for caret. There is no way to tell between AND sign and
caret. In addition, centered-dot, gamma, delta, and circle-plus are not
displayed (they generate an error message).
Visible INPUT MAPPINGS:
αz and αZ are mapped to [CALL], αβz and αβZ are mapped to α[CALL]; α_ is
mapped to [BACK NEXT] and αβ_ is mapped to β[BACK NEXT]. ↑ is mapped to
caret; to send ↑ (distinct from VT) see below. Some other more obscure
characters must be sent by using a command; see below.
COMMANDS:
[ESCAPE]I is used to enter a SUPDUP command. The following commands are
defined:
F Use Fast display mode (discussed below).
K or L Kill the job on ITS and break network connections.
P Temporarily restore the page printer. Typing any
character will return your screen to ITS.
Q Quit out, close network connections, detach the job
on ITS if there is one.
R Record contents of screen onto a file; asks you for
name of file to write.
S Use Slow display mode (see below).
V Re-draw the current screen.
? Type a help text.
Command mode also allows some of the more esoteric ITS characters to be
sent. For example, ↑, α↑, β↑, αβ↑, αz, αβz, αZ, αβZ, α_, and αβ_ are sent
in image mode without being mapped. Special mappings exist for keys not
on the keyboard or trapped by the monitor. They may be sent with bucky
bits, and they have no explicit graphic here or on ITS, as they are
special function keys. These are:
. centered-dot [TAB] gamma [LF] delta
[CR] circle-plus [BS] integral ∂ [NULL]
λ [BACK SPACE] ≠ [CALL] ∨ [BACK NEXT]
α [ESCAPE] β [BREAK] ε [CLEAR]
DISPLAY MODES:
SUPDUP has two display modes; fast and slow, which are set by the F and S
commands. Fast mode, which is the default, is highly optimal on network
input and very fast on display. On the other hand, it can be
disconcerting to have the screen flash as suddenly as it does with no
semblance of line- per-line output (it sort of comes out as
chunk-per-chunk), therefore, there is a slow mode which causes SUPDUP to
output in the old-fashioned manner which just does normal optimization but
not line/screen optimization.
Everything nobody wanted to know about SUPDUP's internal mappings
The following character set mappings are in effect. These mappings occur
on both input and output, so in general they are invisible to the user.
In particular, the graphic on the keytop is what ITS will see, and what is
displayed on the screen is what would be displayed on an ITS TV. But see
the second table and notes for exceptions.
SAIL ITS
---- ---
013 VT ↑ (6)
030 _ ←
032 ~ ≠
033 ≠ ALT
136 ↑ ∧ (2)
137 ← _
175 ALT }
176 } ~
177 BS INT (1) (6)
In addition, the following keyboard mappings are done:
KBD code Sent to ITS
--- ---- ---- -- ---
αz [CALL] (3)
αZ [CALL]
αβz α[CALL]
αβZ α[CALL]
α_ [BACK NEXT] (4)
αβ_ α[BACK NEXT]
↑ ∧ (2) (5)
Notes:
(1) This character is image rubout, which on a PDP-11 TV is output as
integral sign.
(2) AND sign (∧) is used for caret since there is no code in the SAIL
character set for caret anyway.
(3) These four mappings are necessary since there is no way that any form
of [CALL] can be read by a user program.
(4) This mapping is necessary since there is no key remotely equivalent to
the [BACK NEXT] key.
(5) This mapping is necessary since otherwise there is no way to enter
caret from the keyboard. As caret is more important on ITS, up arrow
lost. VT will input an up-arrow, however it will not be [TOP]ified,
meaning that in order to enter this character into TECO one must use a
quoting convention or up-arrow as a command; see previous page for
details.
(6) Output only mapping.
⊗
subttl ITS TTY definitions
; These definitions are the various bits, words, etc. for the ITS terminal
; service system calls and are here for convenience and clarity. This is
; abridged from [MIT-AI] SYSTEM;BITS >, the monitor bits definition file.
; TTYOPT variable (terminal capabilities)
sdttop==0 ; for initial value
; Macro to specify that this bit is used by SUPDUP
define use def/
def
irps bit,,[def]
sdttop==sdttop\bit
.istop
termin
termin
%toalt==200000,, ; 1 → standardise altmodes
%toclc==100000,, ; 1 → convert cases on input
use %toers==040000,, ; 1 → this terminal can erase
%tohdx==020000,, ; 1 → half duplex
use %tomvb==010000,, ; 1 → can backspace
use %tosai==004000,, ; 1 → has SAIL graphics
use %tosa1==002000,, ; 1 → init %TSSAI in new jobs (use graphics)
%toovr==001000,, ; 1 → can overprint
use %tomvu==000400,, ; 1 → can line starve (ie a display)
use %tomor==000200,, ; 1 → do **More** processing (init %TSMOR)
%torol==000100,, ; 1 → scroll (init %TSROL for new jobs)
%toraw==000040,, ; 1 → no cursor motion optimization
use %tolwr==000020,, ; 1 → lower case keyboard
use %tofci==000010,, ; 1 → has bucky bit keyboard
%toiml==000004,, ; 1 → acts like a grIMLAC (funny ↑PF, ↑PB)
use %tolid==000002,, ; 1 → can insert/delete lines
use %tocid==000001,, ; 1 → can insert/delete characters
%tpplf==700000 ; LF padding
%tppcr==070000 ; CR padding
%tpptb==007000 ; TAB padding (0 → no tabs, 1 → tabs)
%tptel==000100 ; 1 → CR → CRLF for ARPAnet protocol
use %tpcbs==000040 ; 1 → intelligent terminal protocol (↑\)
%tp11t==000020 ; 1 → PDP-11 TV (reflects %TY11T)
use %tpors==000010 ; 1 → output reset should do something
%tpibc==000002 ; 1 → correspondence code 2741
%tpibm==000001 ; 1 → IBM 2741
; TCTYP variable (terminal type)
%tnprt==0 ; printing console, glass TTY, etc.
%tndp==1 ; good Datapoint
%tnodp==2 ; inferior losing Datapoint
%tniml==3 ; grIMLAC
%tntek==4 ; Tektronix 4000 series
%tntv==5 ; PDP-11 TV
%tnmem==6 ; Memowreck
%tnsfw==7 ; Software
%tntrm==10 ; Terminet
%tnesc==11 ; ASCII standard display (VT52, etc.)
%tndtm==12 ; Datamedia 2500
%tnmax==13 ; 1 + largest terminal type
; Components of an input character in 12-bit mode.
%txasc==0177 ; ASCII part
%txctl==0200 ; control
%txmta==0400 ; meta
%txsft==1000 ; shift
%txsfl==2000 ; shift lock
%txtop==4000 ; top
subttl ITS output buffer codes
; These are the ITS output buffer codes (used by Software terminals).
%tdmov==200 ; move cursor OV OH NV NH
%tdmv1==201 ; move cursor; NV NH
%tdeof==202 ; clear to end of screen
%tdeol==203 ; clear to end of line
%tddlf==204 ; delete character after cursor
%tdmtf==205 ; motor off
%tdmtn==206 ; motor on
%tdcrl==207 ; terpri
%tdnop==210 ; no-op
%tdbs==211 ; backspace
%tdlf==212 ; line feed
%tdrcr==213 ; carriage return
%tdors==214 ; output reset
%tdqot==215 ; quote next character (mystery command)
%tdfs==216 ; cursor forward
%tdmv0==217 ; move cursor NV NH
%tdclr==220 ; clear screen
%tdbel==221 ; feep!
%tdini==222 ; reset reset reset
%tdilp==223 ; insert line; count
%tddlp==224 ; delete line; count
%tdicp==225 ; insert character; count
%tddcp==226 ; delete character; count
%tdbow==227 ; inverse video
%tdrst==230 ; reset inverse video, etc.
%tdmax==231 ; 1 + largest display code
subttl SAIL system definitions
; First define all the UUO's. MIDAS has these predefined, but DDT is
; cretinous.
.insrt SAIDFS[CSP,SYS]
.decdf
; This page contains the SAIL system bits that are used within SUPDUP. It is
; not a complete list of the SAIL system bits.
; SETACT bits
allact==000040 ; all αβ characters and BS activate
bsact== 000020 ; all forms of BS activate
supscm==000004 ; all αβ characters activate
supccr==000002 ; αCR is an ordinary character
; GETLIN/SETLIN bits
dislin==400000,, ; terminal is a III
dmlin== 040000,, ; terminal is a DM
dddlin==020000,, ; terminal is a DD
echarr==010000,, ; terminal echoes arrow for controls
ptylin==004000,, ; terminal is a PTY
impbit==001000,, ; terminal is controlled by a network job
spcbrk==000100,, ; terminal is in special activation mode
; Interrupt condition bits
inttty==020000,, ; TTY input activation
intclk==000200,, ; clock interrupt
intinr==000100,, ; IMP INR
intins==000040,, ; IMP INS
intims==000020,, ; IMP status change
intinp==000010,, ; IMP input waiting
inttti==000004,, ; [ESCAPE]I
; DM UPGIOT flags
trunca==040000,, ; truncate output lines to 80. characters
noeeol==020000,, ; suppress CEOL when moving to a line
noeeob==010000,, ; suppress CEOL on blank line
; Network socket status flags
rfcs== 200000,, ; RFC sent
rfcr== 100000,, ; RFC received
clss== 040000,, ; CLS sent
clsr== 020000,, ; CLS received
; Network I/O status bits
hdead== 002000 ; host or destination IMP dead
ctrov== 001000 ; host sent more bits than allocated
rset== 000400 ; host sent a RST
tmo== 000200 ; time out
; Network status word error codes
siu== 01 ; socket in use
ccs== 02 ; can't change socket numbers
sys== 03 ; horrible system error
nla== 04 ; no links available
ilb== 05 ; illegal byte size
idd== 06 ; IMP dead
; I/O status word error bits
ioimpm==400000 ; improper mode
ioderr==200000 ; hard device error (data missed, etc.)
iodter==100000 ; soft device error (parity error, etc.)
iobktl==040000 ; block number out of bounds
iodend==020000 ; end of file
];if1
subttl Data area
.ystgw ; storage words okay now
; Beginning of core area initialized to zero at startup
corbeg==. ; beginning of data area
cnsblk: block 1 ; CNSGET info
tctyp: block 1 ; TCTYP for server
ttyopt: block 1 ; TTYOPT for server
tcmxv: block 1 ; TTY page length
tcmxh: block 1 ; TTY width
ttyrol: block 1 ; TTYROL variable
cnsbll==.-cnsblk
; Random flags
dmp: block 1 ; -1 → this is a Datamedia
dmluzp: block 1 ; -1 → this is a non-FCS (losing) Datamedia
ddp: block 1 ; -1 → this is a Data Disc
iiip: block 1 ; -1 → this is a III
ptyp: block 1 ; -1 → this is a PTY
netp: block 1 ; -1 → this is a network PTY
prtp: block 1 ; -1 → this is a printing console
filinp: block 1 ; -1 → fill in host name
runcmp: block 1 ; -1 → called via RUN command
slowip: block 1 ; -1 → do input slow way
clsedp: block 1 ; -1 → connection closed by foreign host
imgchp: block 1 ; -1 → image characters from command
ntbfop: block 1 ; -1 → output to net in buffer
; Interrupt level flags
ttiinp: block 1 ; -1 → TTY input pending
ntiinp: block 1 ; -1 → net input pending
ntoinp: block 1 ; <0 → INS pending
escpip: block 1 ; -1 → [ESCAPE]I typed
; Buffer headers
ntibf: block 3 ; net input buffer header
ntobf: block 3 ; net output buffer header
dsibf: block 3 ; disk input buffer header
dsobf: block 3 ; disk output buffer header
; Other random storage
lgrskt: block 1 ; socket from logger
pdl: block pdllen ; pushdown stack
; IMP MTAPE command words
; Connect to host command block
impcod: block 1 ; command
impsta: block 1 ; status
implsk: block 1 ; local socket
impwat: block 1 ; ≠ 0 → wait for connection
impbyt: block 1 ; byte size
impfsk: block 1 ; foreign socket
imphst: block 1 ; foreign host number
; Wait for connection to be completed command block
watcod: block 1 ; command
watsta: block 1 ; status
watskt: block 1 ; socket
; Close connection to host command block
clscod: block 1 ; close code
clssta: block 1 ; close status
clsskt: block 1 ; close socket
clswat: block 1 ; ≠ 0 → wait for close
subttl Display crufties
; Number of words in display frobs
nwrdln==4+nchars/5 ; number of words on a line
scrsiz==nlines*nwrdln ; number of words on screen
ngw==<<nchars*3>+17.>/16. ; number of graphics words
; Cursor position pointers
vpos: block 1 ; vertical position
hpos: block 1 ; horizontal position
ovpos: block 1 ; old vertical position
; Positioning flags
govpos: block 1 ; -1 → get old vertical position
gohpos: block 1 ; -1 → get old horizontal position
gtvpos: block 1 ; -1 → get vertical position
gthpos: block 1 ; -1 → get horizontal position
; Insert/delete mode flags
gtiln: block 1 ; -1 → get # of lines to insert
gtdln: block 1 ; -1 → get # of lines to delete
gtich: block 1 ; -1 → get # of characters to insert
gtdch: block 1 ; -1 → get # of characters to delete
; Screen updating flags
slupdp: block nlines ; -1 → this line has changed
scupdp: block 1 ; -1 → some update happened someplace
saupdp: block 1 ; -1 → updated whole screen
crupdp: block 1 ; -1 → updated cursor
corend==.-1 ; address of top of core
; End of core zeroed upon startup
debugp: block 1 ; -1 → debugging
; Various display programs
; III header word
iiihdr:
.byte 11.,11.,3.,3.,2.,2.,4.
-777 ? 640 ? 4 ? 2 ? 1 ? 2 ? 6 ; invisible absolute vector
.byte
; Display screen display program
scp: ddcmd 1,46,4,1,5,10 ; line address 30
ddcmd 3,2,3,2,3,2 ; go to column 2
screen: block scrsiz ; TV screen storage
scrend=.-1 ; end of screen storage
0 ; end of DD program
scpl==.-scp
botlin=screen+scrsiz-nwrdln+2-1 ; address of start of bottom line
; More display data stuff
; Display cursor display program
scc: ddcmd 1,7,1,7,1,7 ; graphics
ddcmd 3,1,4,0,5,0 ; select position
block ngw ; all graphics columns
ddcmd 0,0,1,46,1,46 ; execute
0 ; end of program
sccl==.-scc
; Line display programs
linprg: ddcmd 1,46,4,0,5,0 ; line update commands
ddcmd 3,2,3,2,3,2
block nwrdln-3
0
; Display commands
; Display screen
sdisp: 600000,,scp ; two field mode
scpl ; size of display program
0 ; no transfer in progress flag
scp ; address of low order line command
; Cursor display
cdisp: 400000,,scc ; address of cursor hacker
sccl ; size of the hacker
0 ; transfer in progress flag
scc+1 ; address of low order line command
cclear: scc ; address of cursor hacker
sccl ; size of the hacker
0 ; no transfer in progress flag
scc+1 ; address of low order line command
; Line display
ldisp: 600000,,linprg ; two field mode
nwrdln ; size of this command
0 ? linprg ; t-i-p flag
; Byte pointer table for insertions
scbytp: 350700,,(y)
260700,,(y)
170700,,(y)
100700,,(y)
010700,,(y)
; DM display programs and stuff
dmdisp: trunca\noeeol\noeeob+dmpgm ; truncate, no ceol
0 ? 0 ; # words, t-i-p flag
dmpgm: block dmbufl ; DM display program
dmcnt: 0 ; DM program counter
dmpnt: 0 ; DM program counter
subttl UUO server
; UUO server. Only allows BURP UUO (op code 037).
; BURP [OP=037]
; --------------------------------------------------
; BURP ADR
;
; ADR: <asciz string>
;
; The BURP UUO types out the ASCIZ string that starts at location ADR.
; message. If the DEBUGP runtime switch is set, BURP bops into DDT if
; DDT is present; RETURN[ALT]X from DDT attempts to return. BURP should
; not be called from interrupt level.
; A non-zero AC field means the error is fatal.
BURP=037000,, ; UUO for logging cruft
BARF=burp 1, ; UUO for fatalities
pgmbeg==. ; start of pure core
tmploc job41,call uuoser ; UUO server
uuoser: save t ? save u ; save the old UUO AC's
save jobuuo ; and the UUO itself
ldb u,[.bp %icopc,jobuuo] ; get op code
caxe u,burp←-27. ; was it a BURP UUO?
barf [asciz/Illegal UUO!
/] ; isn't recursion wonderful?
ldb u,[.bp %icacf,jobuuo] ; get AC field
outstr @(p) ; type the message
skipn u ; fatal error?
skipe debugp ; debugging?
call ddtcal ; yes, call DDT
adjsp p,-3 ; drop stack
return ; return to user
; Call DDT
ddtcal: call echon ; turn echoing back on
skipn u,jobddt ; get start addr of DDT
jrst [ exit 1, ; no DDT!!!
jrst ddtret] ; continue...
outstr [asciz/You're in DDT.
/]
call (u) ; call DDT
ddtret: ptjobx [0 ? sixbit/DOFF/] ; turn echoing off
skipe prtp ; not for printing console
return ; 'cause they are losers
ppact ; flush PP
store %fword,saupdp ; must fix whole screen
leypos 2000 ; throw away line editor
return ; and return
; Turn echoing back on (this so it can be called from bkpt)
echon: ptjobx [0 ? sixbit/DON/] ; turn echoing on
hrroi t,[004000,,400\"N] ; [BREAK]N
skipn prtp ; not for printing console
ttyset t, ; back to page printer
return ; return to caller
subttl Interrupt server
intser: movn i,jobcni ; -reason
andca i,jobcni ; set to 0 iff only one bit set
jumpn i,mulint ; lossage!
skipn i,jobcni ; get reason for interrupt
jrst noint ; no interrupt set?
txze i,intclk ; clock int?
txo i,inttty\intinp ; yes, fake TTI and NTI int
txze i,inttty ; TTY int?
store %fword,ttiinp
txze i,intinp ; network interrupt?
store %fword,ntiinp
txze i,intins ; IMP INS?
sos ntoinp
txze i,inttti ; [ESCAPE]I?
store %fword,escpip
txze i,intims ; IMP status change?
store %fword,clsedp
jumpn i,uknint ; known interrupt?
dismis ; yes, dismiss the interrupt
; Interrupt-level errors
uknint: outstr [asciz/Unknown interrupt!
/]
jrst intluz
mulint: outstr [asciz/More than one interrupt bit set!
/]
jrst intluz
noint: outstr [asciz/Interrupt with no interrupt bits!
/]
; jrst intluz
intluz: uwait ; finish UUO, restore AC's
save jobtpc ; save PC of interrupt
intmsk [0] ; forbid interrupts
debreak ; enter user mode
call ddtcal ; now enter DDT
intmsk [%fword] ; allow interrupts again
return ; return to interrupted program
subttl Startup, etc.
; Initialize the world; clear all I/O and other things; give
; back any unneeded core to the monitor; clear data area, and
; set up the stack pointer.
supdup: jfcl ; flush CCL crufties
reset ; reset all I/O
skipe debugp ; debugging?
outstr [asciz/Debugging version!
/]
movei intser ; get addr of interrupt server
movem jobapr ; tell monitor
hlrz jobsa ; get size I should be
skipn debugp ; debugging?
movei sdpff ; no, then okay to flush DDT
hrlm jobsa ; but make sure monitor knows now
movem jobff ; make sure monitor knows
core ; in case I grew
barf [asciz/CORE UUO failed!
/] ; goddam ungrateful monitor!
skipe debugp ; debugging?
jrst supdp1 ; yes, can't flush DDT
hrrz jobddt ; get addr of DDT
caige sdpff ; it is below pgm?
jrst supdp1 ; yes, didn't flush DDT
movx x,%zeros ; no, flushed DDT, flush DDT's start addr
setddt x, ; tell monitor (sigh)
supdp1: store %zeros,corbeg,corend ; clear data area
setzb @jobff ; clear first word of garbage
adjsp @jobff ; make zapping pointer
aos ; point to next word
blt @jobrel ; now flush this trash
move p,[pdl(-pdllen)] ; load PDP
; (continued on next page)
; Initial terminal setup
; Set up terminal codes for ITS and the sort of display we are
store <<1-cnsbll>,,>,cnsblk ; Moon's new protocol
store %tnsfw,tctyp ; software TTY
store sdttop,ttyopt ; what we can support
store nlnglt,ttyrol ; scroll count
move [-2,,[6000,,tcmxh ? 15000,,tcmxv]]
ttyset ; get screen size information
sos tcmxv ? sos tcmxv ; don't garble who-line
sos tcmxh ; also allow for "!" on line overflow
; Check terminal characteristics
movx x,%fword ; my console
getlin x ; get my line characteristics
caxn x,%fword ; detached?
exit ; yes, die die die
txne x,ptylin ; a PTY?
store %fword,ptyp ; what a pity (I like puns)
txnn x,impbit ; IMP PTY?
jrst nothop ; nope
store %fword,netp ; net hopper!
outstr [asciz/Foo you are a net hopper.
/]
nothop: skipge tcmxv ; really PTYful?
jrst sdpprt ; yes, don't claim to be a display
txne x,dislin ; III?
store %fword,iiip ; yes
txne x,dddlin ; Data Disc?
store %fword,ddp ; yes
txne x,dislin\dddlin ; is this a local display?
jrst sdpdpy ; yup, it's a display
txne x,dmlin ; Datamedia?
jrst [ store %fword,dmp ; yes
hrroi [21000,,y] ; Datamedia state flags
ttyset ; (right half of DMFLAG in DPY header)
txnn y,4000 ; bit 2.3 → FCS DM
sosa dmluzp ; nope, loser
jrst sdpdpy ; now continue
movx y,%tosai\%tosa1 ; FCS bits
andcam y,ttyopt ; tell ITS we don't have SAIL graphics
jrst sdpdpy] ; and continue
sdpprt: store %fword,prtp ; flag printing console
store %tnprt,tctyp ; printing console
store %tomvb\%toovr\%tolwr\%tomor\%toraw,ttyopt; with minimal options
store move,tcmxv ; ∞ page size
txz x,dislin\dddlin\dmlin ; prevent PTYJOB fuckups
; Set terminal activate on all characters
sdpdpy: txo x,spcbrk ; special activation mode bit
setlin x ; enter SAM
setact [[777777,,777777 ; activate on 000 - 043
777777,,777777 ; 044 - 107
777777,,777777 ; 110 - 153
777777,,600000\allact\bsact\supscm\supccr]]; 154 - 177, αβ act
ptjobx [0 ? sixbit/DOFF/] ; turn echoing off
; jrst chfhnm ; now check for host name
subttl Monitor command processor
; Check for host name in the monitor command line. Yes, I realize this
; code is totally wierd!!!
chfhnm: rescan x ; get monitor command cruft back
jumpe x,gethst ; no cruft, ask for it
moncom: inchrs x ; got a command, gobble a character
jrst gethst ; lost, do it manually
caxl x,"a ; lower case?
caxle x,"z ; . . .
caxa ; no
subx x,"a-"A ; yes, uppercaseify
skipn runcmp ; already checked for RUN command?
jrst [ caxe x,"R ; is it a RUN command?
aosa runcmp ; nope
store %fword,runcmp ; yes, no spaces checked!
jrst .+1] ; now return
skipl runcmp ; called via RUN command?
caxe x,<" > ; space frob? (only if not RUN)
caxn x,<";> ; or comment?
caxa ; yup, hack it
jrst moncom ; haven't gotten there yet, try again
move b,[jsp y,[ inchrs x ; yes, load subroutine
jrst badhst ; lost
caxl x,"a ; lower case?
caxle x,"z ; . . .
caxa ; no
subx x,"a-"A ; yes
caxn x,<" > ; found space?
jrst -1(y) ; yes, flush it
jrst (y)]] ; end of subroutine
jrst scnhst ; and scan for this host
subttl Get host name
gethst: outstr [asciz/Host = /]
move b,[jsp y,[ inchrw x ; subroutine for non-monitor command
caxl x,"a ; lower case?
caxle x,"z ; . . .
caxa ; no
subx x,"a-"A ; yes, uppercaseify
outchr x ; echo the whatever
jrst (y)]] ; end of non-monitor subroutine
store %fword,filinp ; remember to fill in host name
scnhst: xct b ; get a character
caxn x,"A ; AI Lab?
jrst [ skipe filinp ; fill in host name?
outstr [asciz/I
/]
movx a,sixbit/SD AI/ ; select host name
setnam a, ; and tell monitor
movx a,206 ; MIT-AI
jrst goicp] ; now ICP
caxn x,"D ; Dynamod?
jrst [ skipe filinp ; fill in host name?
outstr [asciz/M
/]
movx a,sixbit/SD DM/ ; select host name
setnam a, ; and tell monitor
movx a,106 ; MIT-DMS
jrst goicp] ; now ICP
caxe x,"M ; MathLab LCS place?
badhst: jrst [ outstr [asciz/?
/]
clrbfi ; flush input buffer
jrst gethst]
xct b ; get another character
caxl x,"a ; lower case?
caxle x,"z ; . . .
caxa ; no
subx x,"a-"A ; uppercaseify
caxn x,"C ; MACSYMA consortium?
jrst [ movx a,sixbit/SD MC/ ; select host name
setnam a, ; and tell monitor
movx a,354 ; MIT-MC
skipe filinp ; filling in?
outstr [asciz/
/]
jrst goicp] ; now ICP
caxe x,"L ; Autoprog?
jrst badhst ; nope, losey
movx a,sixbit/SD ML/ ; select host name
setnam a, ; tell monitor
movx a,306 ; MIT-ML
skipe filinp ; filling in?
outstr [asciz/
/]
; jrst goicp ; now ICP
subttl ICP ICP ICP
goicp: clrbfi ; clear any crlf, etc.
outstr [asciz/ Trying... /]
; Open channels and set timeouts
init icp,17 ; open ICP in dump mode
'IMP,, ; ARPAnet
0 ; no buffers
barf [asciz/Can't OPEN the IMP!
/]
mtape icp,[ 17 ; set timeouts
.byte 6 ? 2 ? 24 ? 0 ? 7 ? 7 ? 0]
init net,0 ; open NET in ASCII mode
'IMP,, ; ARPAnet
ntobf,,ntibf ; buffers
barf [asciz/Can't OPEN the IMP!
/]
mtape net,[ 17 ; set timeouts
.byte 6 ? 2 ? 24 ? 0 ? 7 ? 0 ? 0]
; Try to generate a unique socket number, using job number and
; time of day to avoid lossage due to old connections.
; Algorithm used is: job #,,<time&777770>
pjob x, ; get my job #
mstime y, ; and the time now
lsh x,18. ; put job # in LH
hrri x,(y) ; and time in RH
andx x,37777777770 ; but zap low order bits
; Now try to get to the foreign place's server
insirp setzm,[impcod impsta impbyt]
store %fword,impwat ; do wait until timeout
movem x,implsk ; my socket to use
movem x,clsskt ; socket to close when done
movem a,imphst ; host to go to
store icpskt,impfsk ; socket to ICP on
mtape icp,impcod ; connect → foreign logger
move x,impsta ; get status
txne x,77 ; error code?
jrst conerr ; yes, report MTAPE lossage
getsts icp,y ; get error stats for message
txne y,ioimpm\ioderr\iodter\iobktl\iodend\hdead\ctrov\rset\tmo
jrst iioerr ; so sorry
txc x,rfcs\rfcr ; for next instruction to win
txne x,rfcs\rfcr ; RFC sent+received?
jrst [ txne x,clss\clsr ; close sent?
jrst refuse ; yes, refused
movx y,tmo ; no, fake time out
jrst iioerr] ; and output error message
hrroi y,impfsk-1 ; get ready to get a word
movx z,%zeros ; stop after
; (continued on next page)
; Get socket number from logger
in icp,y ; get socket from logger
caxa ; won
jrst nosock ; didn't get socket number!
ldb x,[044000,,impfsk] ; get socket we got
movem x,impfsk ; and save it back
store 3,clscod ; close code
mtape icp,clscod ; close off ICP socket
releas icp, ; free up channel
; Got socket number from logger; now connect output
movx x,3 ; ICP/transmit offset
addb x,implsk ; local transmit socket
movem x,watskt ; save wait socket
store %zeros,impwat ; don't wait
store 8.,impbyt ; byte size
mtape net,impcod ; connect → server output
move x,impsta ; get status
txne x,77 ; only error code
jrst conerr ; error?
; Now connect input
sos implsk ; local receive socket
aos impfsk ; foreign transmit socket
mtape net,impcod ; connect ← server input
move x,impsta ; get status
txne x,77 ; only error code
jrst conerr ; lose lose lose
; Connections started, now wait for output
store 4,watcod ; WAIT code
mtape net,watcod ; wait for output
move x,watsta ; get status
txne x,77 ; only error code
jrst conerr ; lose lose lose
getsts net,y ; get error bits for message
txne y,ioimpm\ioderr\iodter\iobktl\iodend\hdead\ctrov\rset\tmo
jrst iioerr ; too bad
txc x,rfcs\rfcr ; for next instruction to win
txne x,rfcs\rfcr ; RFC sent+received?
jrst [ txne x,clss\clsr ; close sent?
jrst refuse ; yes, refused
movx y,tmo ; no, fake a time out
jrst iioerr] ; and report it
; Output connected, now wait for input
sos watskt ; now select receive socket
mtape net,watcod ; wait for input
move x,watsta ; get status
txne x,77 ; only error code
jrst conerr ; error?
getsts net,y ; get error bits for message
txne y,ioimpm\ioderr\iodter\iobktl\iodend\hdead\ctrov\rset\tmo
jrst iioerr ; too bad
txc x,rfcs\rfcr ; for next instruction to win
txne x,rfcs\rfcr ; RFC sent+received?
jrst [ txne x,clss\clsr ; close sent?
jrst refuse ; yes, refused
movx y,tmo ; no, fake a time out
jrst iioerr] ; and continue
outstr [asciz/Open
/]
; (continued on next page)
subttl Final pre-display initialization
; Random other pre-execution initialization crufties
movx x,8. ; 8 bit bytes you know
dpb x,[300600,,ntibf+1] ; hack input buffer
dpb x,[300600,,ntobf+1] ; and output buffer
movx x,inttty\intclk\intinr\intins\intims\intinp\inttti
clkint 60.*clkspd ; set clock ticking
intenb x, ; enable interrupt conditions
mtape net,[15 ? 1] ; maximum allocation
; Send terminal characteristics
move z,[440600,,cnsblk] ; load sixbit pointer to TTY chars
movx y,6*cnsbll ; load number of bytes to do
ttchsn: ildb x,z ; get a character
call netoc1 ; output it
sojg y,ttchsn ; loop until done
call netsnd ; now force it out
; Now get server's greeting message
grtmsg: call netich ; get a character from the network
caxn x,%tdnop ; hit the no-op yet?
jrst grtdun ; yes, greeting message done
outchr x ; output it
jrst grtmsg ; and loop for next
subttl Slurp up and send terminal ID
; Tell SUPDUP server to expect terminal name
grtdun: movx x,300 ; escape to SUPSER
call netoc1 ; send it
movx x,302 ; set TTY id
call netoc1 ; send it
skipe netp ; is it a network user?
jrst [ move y,[440700,,[asciz/Network terminal/]]
jrst sndid1] ; and send it
skipe ptyp ; is it a PTY?
jrst [ move y,[440700,,[asciz/Pseudo terminal/]]
jrst sndid1] ; and send that
; Now try to get the file
open dsk,[0 ? 'DSK,, ? dsibf] ; try to get a DDB
barf [asciz/Can't OPEN the DSK!
/]
movx x,sixbit/ROOMS/ ; file name
setzb y,z ; extension, date cruft
movx a,sixbit/ PDOC/ ; PPN
lookup dsk,x ; try to find file
jrst [ burp [asciz/ROOMS[P,DOC] is gone!
/]
jrst rndtid] ; lose
; Compute name we must look for
hrroi y,[17000,,y] ; my responsible TTY
ttyset y, ; get my TTY #
jumpe y,fndrom ; found it now if TTY 0
; jrst search ; and search for it
; Now search for terminal
search: call getch ; get a character
call getch ; got CR, get the LF (we're trusting)
jrst search ; no line feed
sojg y,search ; got line feed, punt if done
; Found the terminal name, now flush TTY name and spaces
movx y,8. ; skip over TTY name
fndrom: call getch ; gobble down TTY name
jrst [ burp [asciz/ROOMS[P,DOC] in bad format!
/]
jrst rndtid] ; somebody better fix ROOMS[P,DOC] !!
sojg y,fndrom
caxn x,<" > ; space?
jrst flsspc ; yes, roomless TTY
sndrom: call netoc1 ; send character out
call getch ; get a character
jrst [ burp [asciz/ROOMS[P,DOC] in bad format!
/]
jrst rndtid] ; somebody better fix ROOMS[P,DOC] !!
caxe x,<" > ; saw a space?
jrst sndrom ; nope, okay to send it
call netoc1 ; well, can send one space
flsspc: call getch ; but not any more
jrst rndrom ; all done
caxn x,<" > ; a space to flush?
jrst flsspc ; yes, flush it
sndtid: call netoc1 ; not a space, send it
call getch ; get a character
caxa ; all done
jrst sndtid ; no, send it out
; Done with sending room, finish that up and get going on real work
sntrom: movx x,%zeros ; final null
call netoc1 ; send it
tidone: call netsnd ; force the buffer out
release dsk, ; free up channel
; (continued on next page)
subttl Initialize screen
skipe prtp ; printing console?
jrst [ store 5*dmbufl,dmcnt ; initialize counter
move [440700,,dmpgm] ; initialize pointer
movem dmpnt ; . . .
jrst loser] ; and flush display garbage
store %zeros,hpos ; to beginning of line
store %zeros,vpos ; top of screen
ppact ; flush PP 0
leypos 2000 ; line editor off screen
skipn dmp ; is it a DM?
jrst chkiii ; no, check for III
store 5*dmbufl,dmcnt ; initialize DM counter
move [440700,,dmpgm] ; initialize DM pointer
movem dmpnt ; . . .
jrst inidpy ; and continue
chkiii: skipn iiip ; cretinous III?
jrst inidpy ; nope
store %zeros,scp ; all III frobs start with zero
move iiihdr ; get III header
movem scp+1 ; stuff in III program
inidpy: call scrini ; init core screen
store %fword,ovpos ; old vertical position
loser: lock ; now get locked in core
; Top level sleeper
sleepr: call scnupd ; update screen if necessary
iwait ; sleep until next interrupt
aosg escpip ; woke up, got a command?
jrst cmdcmd ; yes, do the command
aosg ttiinp ; TTY input?
jrst ttiser ; loop around again
aosg ntiinp ; net input?
jrst ntiser ; hack it
jrst sleepr ; else back to sleep
subttl TTY input service
ttiser: inchrs x ; got a character?
jrst [ aosg ntbfop ; was there network output?
call netsnd ; force the buffer out
aosg ntiinp ; net input?
jrst ntiser ; yes, hack it
jrst sleepr] ; nope, back to main loop
skipe prtp ; printing console?
jrst [ move y,x ; dumb ALLOMP
call allomp ; map to ASCII
move x,y ; get character back
caxn x,↑↑ ; and even more marginal ↑↑ feature
jrst [ store %fword,escpip; yes, pretend [ESCAPE]I
jrst ttiser] ; and continue
caxn x,%txctl\%txmta\↑J ; αβ[LF]?
movx x,↑Z ; yes, convert to ↑Z
jrst .+1] ; and continue
ldb y,[000700,,x] ; get ASCII part of X
caxn y,↑M ; terpri?
inchrw y ; gobble line feed
store %fword,ntbfop ; flag there is network buffered output
call netoch ; send it out
jrst ttiser ; and try for any frobs just came in
; Force the buffer out to the network
netsnd: ldb x,[410300,,ntobf+1] ; load position field
movx y,1 ; get a bit to hack
lsh y,(x) ; 2↑# of characters
subx y,1 ; now get null bit flusher mask
iorm y,@ntobf+1 ; make sure the nulls aren't sent
out net, ; send the character
return ; won
jrst nioerr ; lost
; Auxillary NETOCH
netoc1: sosg ntobf+2 ; space available in buffer?
out net, ; no, output the buffer
caxa ; win
jrst nioerr ; lose
idpb x,ntobf+1 ; put character in buffer
return ; and return
; Output a character to the network buffer in the hairy way
netoch: skipe prtp ; printing console?
jrst netoc1 ; yes, no hair allowed
aosn imgchp ; image characters?
jrst ntoc2a ; yes, don't map then
; Map αZ to [CALL], αβZ to α[CALL], α_ to [BACK NEXT], αβ_ to α[BACK NEXT].
; αz and αβz will behave in a similar manner.
; These mappings are necessary since there is no way that SUPDUP can read a
; [CALL] coming in for the Stanford keyboard, and there is no [BACK NEXT] key
; on them. For various other obscure characters, commands exist to send them.
ldb y,[001000,,x] ; get αcharacter
caxe y,%txctl\"z ; some form of αz?
caxn y,%txctl\"Z ; or of αZ?
jrst [movx y,↑Z ; yes, convert to [CALL]
dpb y,[001000,,x] ; save character
txze x,%txmta ; αβz or αβZ?
iorx x,%txctl ; yes, make it α[CALL]
jrst netoc3] ; now send this bucky command
caxn y,%txctl\"_ ; α_?
jrst [ movx y,↑← ; yes, convert to [BACK NEXT]
dpb y,[001000,,x] ; save character
txze x,%txmta ; αβ_?
iorx x,%txctl ; yes, make it α[BACK NEXT]
jrst netoc3] ; now go send the frob
; Map the character from the SAIL to the ITS character set and check for
; if TOPififcation is needed (TECO will treat SAIL graphics as controls
; unless %TXTOP is on). Then check for any bucky bits.
netoc2: ldb y,[000700,,x] ; get ASCII part of character
call outmap ; map to ITS ASCII
dpb y,[000700,,x] ; and kludge back
caxl y,↑I ; TAB is not TOPified
caxle y,↑M ; neither are LF, VT, FORM, and CR
caxn y,<↑[> ;]neither is ALT
jrst ntoc2a ; nope, it's a positioning(?) frob
caxge y,<" > ; all SAIL graphics
iorx x,%txtop ; are TOPified (happy TECO)
ntoc2a: txnn x,%txtop\%txsfl\%txsft\%txmta\%txctl; any bucky bits?
jrst [ call netoc1 ; nope, just send the frob
caxn x,"≤ ; sending the escape code?
call netoc1 ; yes, repeat it
return] ; now return
; The character has bucky bits, so the intelligent terminal protocol is used to
; send bucky bits: [↑\] [<bucky bits>←-7] [<character>].
netoc3: move y,x ; swap swap swap
movx x,↑\ ; load escape code
call netoc1 ; put character in buffer
movx x,"@ ; initialize bucky word
irps bucky,,[%txtop %txsfl %txsft %txmta %txctl]
txze y,bucky ; bucky bit?
txo x,bucky←-7 ; yup
termin
call netoc1 ; send this cruftie out
move x,y ; swap back
call netoc1 ; now send the non-bucky character
return ; and return
; Output mapping from SAIL to ITS character set.
outmap: skipe dmluzp ; losing DM?
jrst allomp ; yah, don't do FCS mappings
mapit y,137,030 ; backarrow
mapit y,030,137 ; underscore
mapit y,033,032 ; not equals
; Common mappings for everything
allomp: mapit y,032,176 ; tilde
mapit y,175,033 ; diamond
mapit y,176,175 ; right curly bracket
return ; else return
subttl Network input service
; Read a character but don't hang.
ntiser: sosg ntibf+2 ; anything in buffer?
jrst [ hrrz x,ntibf ; nope, pointer to next
hrrz x,(x) ; check next
skipge (x) ; anything in next buffer?
jrst [ in net, ; yes, get a new buffer
jrst .+1 ; won
jrst nioerr] ; lost
mtape net,[10] ; no, any input available?
jrst sleepr ; nope, back to sleep
in net, ; yes, get a new buffer
jrst .+1 ; won
jrst nioerr] ; lost
call nulfls ; flush nulls
jrst ntiser ; nulls got flushed
ldb x,ntibf+1 ; get a byte
skipe prtp ; printing console?
jrst [ jumpe x,ntiser ; flush nulls
caxl x,177 ; and non ASCII
jrst ntiser ; gets flushed too
sosg dmcnt ; any room in buffer?
call prtout ; no, output the buffer
call allimp ; map output
idpb x,dmpnt ; save character
jrst ntiser] ; and continue
caxe x,%tdors ; got an output reset?
skipl ntoinp ; still hacking output reset?
caxa ; no output flushing
jrst ntiser ; sigh
; Check for any display stuff that must be done
aosn govpos ; get old vertical position?
jrst [ store %fword,gohpos ; yes, now get old horizontal position
jrst ntiser] ; and try for next
aosn gohpos ; get old horizontal position?
jrst [ store %fword,gtvpos ; yes, get vertical position now
jrst ntiser] ; and try for next
aosn gtvpos ; get vertical position?
jrst [ store %fword,gthpos ; yes, get horizontal position now
movem x,vpos ; save current vpos now
store %fword,crupdp ; flag cursor updated
jrst ntiser] ; and try for next
aosn gthpos ; get horizontal position?
jrst [ movem x,hpos ; set horizontal position
store %fword,crupdp ; flag cursor updated
skipn dmp ; is this a DM?
jrst ntiser ; no, return
dmcmd ↑L ; send a cursor position
move x,hpos ; x position
xorx x,140 ; DM crock
call dmchar ; output the character
move x,vpos ; y position
addx x,2 ; give who-line room
xorx x,140 ; DM crock
call dmchar ; output the character
jrst ntiser] ; and continue
; (continued on next page)
; Check for other display stuff
aosn gtiln ; insert lines?
jrst inslin ; yup
aosn gtdln ; delete lines?
jrst dellin ; yup
aosn gtich ; insert characters?
jrst inschr ; yup
aosn gtdch ; delete characters?
jrst delchr ; yup
caxl x,%tdmov ; display code?
jrst dpyser ; yes, go do special things
; Check for garbage received and flush it
jumpe x,[ burp [asciz/Cannot display centered-dot!
/]
jrst ntiser] ; I think NULs can't happen anymore
caxn x,↑I ; tab?
jrst [ burp [asciz/Cannot display gamma!
/]
jrst ntiser] ; this shouldn't happen
caxn x,↑J ; image LF?
jrst [ burp [asciz/Cannot display delta!
/]
jrst ntiser] ; should not happen
caxn x,↑M ; image CR?
jrst [ burp [asciz/Cannot display circle-plus!
/]
jrst ntiser] ; should not happen
; Good character, so display it
call inpmap ; map from ITS to SAIL ASCII
call scstor ; store it on the screen
jrst ntiser ; continue until this frob empty
; Subroutines for network input service
; Read a character from the network, hanging for it
netich: sosg ntibf+2 ; anything in buffer?
in net, ; nope, get some
caxa ; won
jrst nioerr ; lost
call nulfls ; call null flusher crock
jrst netich ; nulls got flushed
ldb x,ntibf+1 ; get a byte
skipe prtp ; printing console?
jrst allimp ; yes, only map printing characters
; jrst inpmap ; map from ITS to SAIL ASCII
; Map graphics from ITS extended ASCII to SAIL's extended ASCII.
; First come mappings necessary between SAIL and ITS ASCII
inpmap: skipe dmluzp ; losing DM?
jrst allimp ; yah, too bad
mapit x,013,136 ; uparrow
mapit x,030,137 ; left arrow
mapit x,032,033 ; not equals
mapit x,033,175 ; diamond
mapit x,136,004 ; caret (sigh!!!)
mapit x,137,030 ; underscore
mapit x,177,013 ; integral sign
; Then come mappings which are done going anywhere
allimp: mapit x,175,176 ; right curly brace
mapit x,176,032 ; tilde
return ; and return
; Flush padding nulls. Also bumps the byte pointer
nulfls: ibp ntibf+1 ; point to word
move x,@ntibf+1 ; get word of that byte
andx x,17 ; only marking bits
jffo x,.+2 ; count leading zeros
jrst cpopj1 ; no nulls to flush
movni x,-44(y) ; get -1,,# of padding characters
movei y,-1(x) ; # of characters to take off buffer
subm y,ntibf+2 ; remove padding characters from count
movns ntibf+2 ; SUBM goes the wrong way, fix it
adjbp y,ntibf+1 ; move byte pointer
movem y,ntibf+1 ; save pointer
lsh x,3 ; # of bits to shift over
movni x,(x) ; reverse direction
move y,@ntibf+1 ; get word we are hacking
lsh y,(x) ; right justify its bytes
movem y,@ntibf+1 ; store it back again
return ; normal return
subttl Display hacking
dpyser: caxl x,%tdmax ; a baddie?
jrst [ outstr [asciz/Spurious input %TD code (/]
idivx x,100 ; get hundreds
idivx y,10 ; and tens and ones
repeat 3,[
addx x+.rpcnt,"0 ; ASCIIify
outchr x+.rpcnt ; and print it
] ; once for each digit
burp [asciz/) flushed.
/]
jrst ntiser] ; yes, report it
xct dpyctb-%tdmov(x) ; no, dispatch on it
jrst ntiser ; return
; Dispatch table for ITS cursor control codes. The server for
; a display code is defined by:
; DPYSVR code,server instruction
; The servers must be in order by their codes!
define dpysvr code,server
ifn .-dpyctb-code+%tdmov,.err code is out of order
server
termin
dpyctb: dpysvr %tdmov,[store %fword,govpos]
dpysvr %tdmv1,[store %fword,gtvpos]
dpysvr %tdeof,[call clreof]
dpysvr %tdeol,[call clreol]
dpysvr %tddlf,[call clr1ch]
dpysvr %tdmtf,[burp [asciz/Spurious input %TDMTF flushed.
/]]
dpysvr %tdmtn,[burp [asciz/Spurious input %TDMTN flushed.
/]]
dpysvr %tdcrl,[call terpri]
dpysvr %tdnop,[jfcl]
dpysvr %tdbs,[burp [asciz/Spurious input %TDBS flushed.
/]]
dpysvr %tdlf,[burp [asciz/Spurious input %TDLF flushed.
/]]
dpysvr %tdrcr,[burp [asciz/Spurious input %TDRCR flushed.
/]]
dpysvr %tdors,[call oreset]
dpysvr %tdqot,[burp [asciz/Spurious input %TDQOT flushed.
/]]
dpysvr %tdfs,[call csraos]
dpysvr %tdmv0,[store %fword,gtvpos]
dpysvr %tdclr,[call clrscn]
dpysvr %tdbel,[call bredle]
dpysvr %tdini,[burp [asciz/Spurious input %TDINI flushed.
/]]
dpysvr %tdilp,[store %fword,gtiln]
dpysvr %tddlp,[store %fword,gtdln]
dpysvr %tdicp,[store %fword,gtich]
dpysvr %tddcp,[store %fword,gtdch]
dpysvr %tdbow,[burp [asciz/Spurious input %TDBOW flushed.
/]]
dpysvr %tdrst,[burp [asciz/Spurious input %TDRST flushed.
/]]
ifn .-dpyctb-%tdmax+%tdmov,.err %TDMAX is wrong
subttl Display subroutines
; Here to initialize the screen image in core
scrini: store ascii/ /+1,screen,scrend; write blanks throughout screen
movx x,<ascii/
/+1> ; DD type of terpri
movx y,%zeros ; top line
movx z,1 ; blank word
movx a,nlines ; do for number of lines on screen
scrin1: movem z,screen(y) ; zap first word on line
movem z,screen+1(y) ; and second one too
movem x,screen+nwrdln-2(y) ; put terpri at end
movem z,screen+nwrdln-1(y) ; and nothingness after that
addx y,nwrdln ; go to next line
store %zeros,slupdp-1(a) ; line not updated
sojg a,scrin1 ; loop for next line
glnini: store 2,scc+2,scc+2+ngw-1 ; blank graphics word
return ; now return
; Here to store a character on the screen
scstor: move y,vpos ; line position
store %fword,slupdp(y) ; flag this line changed
store %fword,scupdp ; and that there is a change
imulx y,nwrdln ; number words/line
move z,hpos ; x position
camle z,tcmxh ; greater than line length
jrst [ aos hpos ; account for it anyway
return] ; and flush the attempt
idivx z,5 ; word position
addi y,screen+2(z) ; address of word to hack
dpb x,scbytp(z+1) ; save character on screen
aos hpos ; bump X position
skipe dmp ; is this a DM?
jrst dmchar ; yes, output this character
return ; and return
; Here to clear the screen
clrscn: store %zeros,vpos ; top line
store %zeros,hpos ; leftmost column
call scrini ; initialize screen
store %fword,saupdp ; updated entire screen
call scnupd ; now update the screen
skipn dmp ; is this a DM?
return ; no, return
dmcmd ↑← ; clear the screen
dmcmd ↑L ; set cursor position
movx x,140 ; beginning of line
call dmchar ; output the character
movx x,142 ; line 2
call dmchar ; output it
jrst dmout ; force it all out
; Non-insert/delete display subroutines
; Here to clear to EOL
clreol: skipe dmp ; is this a DM?
jrst [ dmcmd ↑W ; yes, send line zapper
jrst .+1] ; and return
move b,hpos ; get the position now
caxl b,linel ; if done
return ; flush
move y,vpos ; get vertical position
store %fword,slupdp(y) ; flag this line changed
store %fword,scupdp ; and that there is a change
imulx y,nwrdln ; number of words/line
move z,hpos ; save horizontal position
idivx z,5 ; word position
addi y,screen+2(z) ; address of word to hack
move z,scbytp(z+1) ; get byte pointer
movx x,<" > ; space in the character
dpb x,z ; zap this character
cleol1: addx b,1 ; bump character pointer
caxl b,linel ; got to EOL yet?
return ; and return
idpb x,z ; zap another character
jrst cleol1 ; nope, not done yet
; Here to delete a character forward
clr1ch: skipe dmp ; is this a DM?
jrst [ dmcmd <" > ; yes, zap out the character
dmcmd ↑H ; back up
jrst .+1] ; and continue
movx x,<" > ; a blank space
move y,vpos ; line position
store %fword,slupdp(y) ; flag this line changed
store %fword,scupdp ; and that a change happened
imulx y,nwrdln ; number of words/line
move z,hpos ; horizonal position
idivx z,5 ; word position
addi y,screen+2(z) ; address to be hacked
dpb x,scbytp(z+1) ; shove character in
return ; and return
; Here to terpri
terpri: skipe dmp ; is this a DM?
jrst [ dmcmd ↑M ; yes, do a CR
jrst .+1] ; and continue
store %zeros,hpos ; to beginning of line
aos y,vpos ; bump vertical position
caml y,tcmxv ; gone too far?
jrst [ move y,[screen+nwrdln,,screen]; foo! gotta scroll (sigh)
blt y,screen+scrsiz-nwrdln-1; the big BLT strikes again
store ascii/ /+1,botlin+1,botlin+<nchars/5>
store %fword,saupdp ; I can't believe I updated the WHOLE thing
move tcmxv ? sos ? movem vpos; set vertical position to bottom line
jrst .+1] ; and continue
store %fword,crupdp ; flag cursor has moved
jrst clreol ; and now clear the line
; More display subroutines
; Here to breedle
bredle: movx x,%fword ; → own speaker
beep x, ; breedle...
return ; and return
; Here to respond to an output reset
oreset: movx x,↑\ ; escape code
call netoc1 ; send it
movx x,↑P ; ready to send cursor position
call netoc1 ; here it comes...
move x,vpos ; vertical position
call netoc1 ; . . .
move x,hpos ; horizontal position
call netoc1 ; . . .
aos ntoinp ; flush one net interrupt
jrst netsnd ; force these crufies out
; Here to forespace
csraos: skipe dmp ; is this a DM?
jrst [ dmcmd ↑\ ; yes, space forward
jrst .+1] ; and continue
aos hpos ; bump horizontal position
store %fword,crupdp ; flag cursor updated
return ; and return
; Here to clear to EOF
clreof: save hpos ; save current horizontal pos
save vpos ; ditto for vertical
cleof1: call clreol ; clear to end of line
store %zeros,hpos ; now clear all of the lines below
aos x,vpos ; bump to new line
caxge x,nlines ; all done yet?
jrst cleof1 ; nope, kill next line
retr vpos ; get back old vertical position
retr hpos ; and horizontal position
return ; and return
; Line insert
inslin: skipn dmp ; is this a DM?
jrst insl0a ; nope
dmcmd ↑P ; yes, enter i/d mode
insl0a: move a,x ; copy # of lines to hack
insln0: skipn dmp ; DM again?
jrst insl1a ; nope
dmcmd ↑J ; insert a line
insl1a: move x,vpos ; load vertical position
imulx x,nwrdln ; make into word counter
addi x,screen ; address of first word of cursor line
cain x,screen+<nlines-1>*nwrdln ; skip unless at bottom line
jrst insln2 ; on bottom, zap it
move y,[screen+<nlines-2>*nwrdln,,screen+<nlines-1>*nwrdln]
insln1: move z,y ; copy pointer
blt z,nwrdln-1(y) ; copy one line
adjsp y,-nwrdln ; offset a line
caie x,(y) ; done yet?
jrst insln1 ; nope
insln2: store ascii/ /+1,2(x) ; blanks
movei y,nwrdln-2-1(x) ; number to do
addx x,3 ; address offset
hrli x,-1(x) ; complete pointer
blt x,(y) ; zak!
sojg a,insln0 ; loop for more lines
store %fword,saupdp ; updated the world
skipn dmp ; on a DM?
jrst ntiser ; no, just return
dmcmd ↑X ; yes, leave i/d mode
jrst ntiser ; and return
; Line delete
dellin: skipn dmp ; is this a DM?
jrst dell0a ; nope
dmcmd ↑P ; yes, enter i/d mode
dell0a: move a,x ; copy # of lines to hack
delln0: skipn dmp ; is this a DM?
jrst dell1a ; nope
dmcmd ↑Z ; delete a line
dell1a: move x,vpos ; get vertical position
imulx x,nwrdln ; frobs to do
addi x,screen ; address of first word of cursor line
cain x,screen+<nlines-1>*nwrdln ; at bottom line?
jrst delln1 ; yup, just copy extra line in
movei y,(x) ; make a copy
addx y,nwrdln ; address of next line
hrli x,(y) ; make a BLT pointer
blt x,screen+<nlines-1>*nwrdln-1; copy the lines
delln1: store ascii/ /+1,2(x) ; blanks
movei y,nwrdln-2-1(x) ; number to do
addx x,3 ; address offset
hrli x,-1(x) ; complete pointer
blt x,(y) ; zak!
sojg a,delln0 ; loop for more lines
store %fword,saupdp ; updated the world
skipn dmp ; on a DM?
jrst ntiser ; no, just return
dmcmd ↑X ; leave i/d mode
jrst ntiser ; and return
; Character insert
inschr: skipn dmp ; is this a DM?
jrst insc0a ; nope
dmcmd ↑P ; yes, enter i/d mode
insc0a: move c,a ; copy character counter
insch0: skipn dmp ; on a DM?
jrst insc1a ; nope
dmcmd ↑\ ; insert a character
insc1a: move x,vpos ; get vertical position
imulx x,nwrdln ; now number of words
move a,x ; copy it for hacking
addi a,screen+nwrdln+3 ; address of last text word
move y,hpos ; get horizontal position
idivx y,5 ; make it words
addi x,screen+2(y) ; address of word with cursor
ldb y,[010700,,(x)] ; first character in next word
ldb b,[ 103400,,(x)
102500,,(x)
101600,,(x)
100700,,(x)
100000,,(x)](z)
dpb b,[ 013400,,(x)
012500,,(x)
011600,,(x)
010700,,(x)
010000,,(x)](z)
movx b,<" > ; space in hole
dpb b,[ 350700,,(x)
260700,,(x)
170700,,(x)
100700,,(x)
010700,,(x)](z)
jrst insch1 ; check for being done
; At each iteration Y has last character, X has next address
insch2: move z,y ; copy the character
ldb y,[010700,,(x)] ; first character in next word
dpb z,[000700,,(x)] ; last character here
move z,(x) ; get word being hacked
rot z,-7 ; put characters in right place
iorx z,1 ; make sure bit 1.1 is on
movem z,(x) ; save character in word
insch1: came x,a ; at last address?
aoja x,insch2 ; nope
store %fword,scupdp ; some update somewhere
move x,vpos ; this line
sojg c,insch0 ; loop for more characters
store %fword,slupdp(x) ; this line was hacked
skipn dmp ; on a DM?
jrst ntiser ; no, just return
dmcmd ↑X ; leave i/d mode
jrst ntiser ; and return
; Character delete
delchr: skipn dmp ; is this a DM?
jrst delc0a ; nope
dmcmd ↑P ; yes, enter i/d mode
delc0a: move c,x ; copy number of characters to hack
delch0: skipn dmp ; on a DM?
jrst delc1a ; nope
dmcmd ↑H ; delete a character
delc1a: move x,vpos ; get current vertical position
imulx x,nwrdln ; number of words
move a,x ; save it for later
addi a,screen+nwrdln-3 ; address of last text word in line
move y,hpos ; get horizontal position
idivx y,5 ; number of words
addi x,screen+2(y) ; address of word with cursor
ldb b,[ 013400,,(x)
012500,,(x)
011600,,(x)
010700,,(x)
010000,,(x)](z)
dpb b,[ 103400,,(x)
102500,,(x)
101600,,(x)
100700,,(x)
100000,,(x)](z)
jrst delch1 ; check for being done
; Each time around the iteration A had address of next word
delch2: ldb y,[350700,,(x)] ; last character in previous
dpb y,[010700,,-1(x)] ; to previous
ldb y,[013400,,(x)] ; get last characters in this word
dpb y,[103400,,(x)] ; put back left justified
delch1: came x,a ; done?
aoja x,delch2 ; not yet
movx y,<" > ; get a space
dpb y,[010700,,(x)] ; blank out last column
store %fword,scupdp ; screen updated someplace
move x,vpos ; get this line
sojg c,delch0 ; hack another character
store %fword,slupdp(x) ; flag this line hacked
skipn dmp ; on a DM?
jrst ntiser ; no, just return
dmcmd ↑X ; leave i/d mode
jrst ntiser ; and return
subttl Display update subroutines
scnupd: skipe prtp ; printing console?
jrst prtout ; yes, update for printing console
skipe slowip ; in slow mode?
jrst scnup1 ; yes, good enough
movx x,<-nlines,,> ; load pointer to line update table
movx y,%zeros ; initialize line count
skipe slupdp(x) ; does this line need hacking?
addx y,1 ; yup, bump count
aobjn x,.-2 ; try for more lines
skipn iiip ; III always updates everything
caxl y,nlnupd ; three lines or so?
store %fword,saupdp ; yup, must update screen
scnup1: aose saupdp ; update entire screen?
jrst scupd1 ; nope, maybe selective
store %zeros,scupdp ; clear other update flags
store %zeros,slupdp,slupdp+nlines-1; . . .
skipe dmp ; is this a DM?
jrst csrupd ; and update the cursor
upgiot sdisp ; output new screen
; jrst csrupd ; now update cursor
; Update cursor
csrupd: skipe dmp ; is this a DM?
jrst [ dmcmd ↑L ; yes, send a cursor pos
move x,hpos ; horizontal position
xorx x,140 ; DM crock
call dmchar ; output it
move x,vpos ; vertical position
addx x,2 ; room for who line
xorx x,140 ; DM crock
call dmchar ; output it
jrst dmout] ; force it out and return
skipn ddp ; is this a DD?
return ; nope, too bad III
skipe cdisp+2 ; finished with the last display?
upgiot [0 ? 0 ? 0 ? 0] ; no, sit and wait
call glnini ; clear cursor line
skipge x,ovpos ; got an old position?
jrst .+3 ; nope, don't try to clear old
call getcsy ; get cursor vertical position
ddupg cclear ; clear cursor
move x,hpos ; horizontal character position
imulx x,6 ; horizontal bit position
addx x,2 ; graphics mode hack
idivx x,32.
movns y
movx z,(740000)
lsh z,(y)
ldb a,[010300,,z]
rot a,-3
andx z,777777777760
iorx z,2
iorx a,2
movem z,scc+2(x)
movem a,scc+3(x)
move x,vpos ; get current vertical position
movem x,ovpos ; save as old position
call getcsy ; get cursor vertical position
ddupg cdisp ; and send it all out
return ; finally return
scupd1: aose scupdp ; did any update happen?
jrst scupd2 ; nope, try for just cursor
movx x,<-nlines,,> ; load line pointer
scup1a: skipe slupdp(x) ; need to hack this line?
call updlin ; yup
aobjn x,scup1a ; loop for next line
jrst csrupd ; now update cursor
scupd2: aose crupdp ; was cursor hacked
return ; nope, just return
jrst csrupd ; yes, then hack the cursor
; More display updating stuff
; Set up display program vertical position
getcsy: imulx x,12.
addx x,24.+10.
dpb x,[140400,,scc+1]
lsh x,-4
dpb x,[240500,,scc+1]
return ; and return
; Display a single line
updlin: skipe dmp ; don't do this garbage if a DM
return ; flitter back immediately
skipe ldisp+2 ; finished with the last display?
upgiot [0 ? 0 ? 0 ? 0] ; no, sit and wait
store %zeros,slupdp(x) ; am updating now
hrrz y,x ; line number
imulx y,nwrdln ; word position
movsi y,screen+2(y) ; address of start of line
hrri y,linprg+2 ; and where line is going to
blt y,linprg+nwrdln-2 ; copy line
hrrz z,x ; get line number again
imulx z,12.
addx z,24. ; starting raster number
dpb z,[140400,,linprg] ; zap in low 4 bits of address
lsh z,-4 ; throw low bits away
dpb z,[240500,,linprg] ; high 5 bits of address
upgiot ldisp ; display the line
return ; now return
; Printing console update routine
prtout: movx z,%fword ; my console
getlin z ; get line characteristics now
txz z,dislin\dddlin\dmlin ; prevent PTYJOB fuckups
save z ; save old status
txz z,echarr ; turn off arrow mode
setlin z ; . . .
outstr dmpgm ; output the cruft
retr z ; get old status back
setlin z ; and reset it
store %zeros,dmpgm,dmpgm+dmbufl-1; clear the old program
store <5*dmbufl>-4,dmcnt ; initialize counter
move [440700,,dmpgm] ; initialize pointer
movem dmpnt ; . . .
return ; and return
subttl DM display routines
; Character output to DM
dmchar: sosg dmcnt ; any room in buffer?
call dmout ; nope, output the buffer
idpb x,dmpnt ; save character
return ; and return
; Redraw DM screen, always skips(!), aborts any undone DM output
dmredw: store %zeros,dmpgm,dmpgm+dmbufl-1; clear the old program
store <5*dmbufl>-4,dmcnt ; initialize DM counter
move [440700,,dmpgm] ; initialize DM pointer
movem dmpnt ; . . .
save hpos ? save vpos ; save current cursor position
dmcmd ↑← ; bop the screen
dmcmd ↑L ; set cursor postion
movx x,140 ; beginning of line
call dmchar ; set X position
movx x,142 ; second line from top
call dmchar ; output that too
store %zeros,vpos ; starting at top
movn z,tcmxv ; get number of lines
hrlzs z ; make it an AOBJN pointer
dmdrw1: movx y,nwrdln ; number of words to offset
imuli y,(z) ; compute offset from start of screen
add y,[440700,,screen+1] ; absolute address of line's characters-1
store %zeros,hpos ; start at beginning of line
dmdrw2: ildb x,y ; get a character from the line
jumpe x,dmdrw2 ; flush nulls
call dmchar ; output the character
aos x,hpos ; bump horizontal position
came x,tcmxh ; gotten to end of the line?
jrst dmdrw2 ; yes
store %zeros,hpos ; end of this line
aos vpos ; bump vertical position
dmcmd ↑M ; new line
aobjn z,dmdrw1 ; and loop for next line
retr vpos ? retr hpos ; get back old cursor position
aos (p) ; bump return PC
; jrst dmout ; and output the mess
; Buffer output to DM; called when DM buffer full or want to force buffer out
dmout: skipn dmpgm ; any program there?
return ; lets not get overenthusiastic
hrrz dmpnt ; get current value of pointer
subi dmpgm-1 ; compute number of words used
movem dmdisp+1 ; set number of words to do
upgiot dmdisp ; output DM program
movs hpos ; get current X position
hrr vpos ; and Y position
addx 0,2 ; give the who line some space
cursor ; bop the cursor to last position
store %zeros,dmpgm,dmpgm+dmbufl-1; clear the old program
store <5*dmbufl>-4,dmcnt ; initialize DM counter
move [440700,,dmpgm] ; initialize DM pointer
movem dmpnt ; . . .
movx 0,177 ; quote
idpb dmpnt ; put in buffer
movx 0,↑L ; cursor position
idpb dmpnt ; bufferify
move hpos ; horizontal position
xorx 0,140 ; DM crock
idpb dmpnt ; bop away
move vpos ; vertical position
addx 0,2 ; who line space
xorx 0,140 ; DM crock
idpb dmpnt ; bop away
return ; and return
subttl SUPDUP commands
cmdcmd: inchrw x ; get command character
ldb y,[001000,,x] ; get αcharacter
caxl y,"a ; lowercase?
caxle y,"z ; . . .
caxa ; no
txz x,<" > ; yes, uppercasify
caxe x,"K ; logout foreign job?
caxn x,"L ; . . .
jrst [movx x,300 ; escape code
call netoc1 ; prepare for escape
movx x,301 ; kill other job code
call netoc1 ; send it too
call netsnd ; now send this command out
outstr [asciz/Logged out foreign job./]
jrst @quit] ; and die
caxn x,"Q ; quit?
quit: jrst [ hrroi y,[004000,,400\"N]; yes, [BREAK]N
skipn prtp ; not on printing consoles
ttyset y, ; clear the screen
exit] ; and exit out
skipe prtp ; these next are only for displays
jrst prtcmd ; so skip them if printing console
; (continued on next page)
; Display only commands
caxn x,"H ; [HELP]?
jrst [ txo x,%txtop ; TOPify
jrst imgsnd] ; and send it out
caxn x,"F ; fast mode?
jrst [ store %zeros,slowip ; yes
outstr [asciz/Fast display mode!
/]
jrst ttiser] ; and continue hacking
caxe x,"? ; help?
caxn x,"P ; page printer restore?
jrst [caxn x,"? ; was it a help?
jsp z,[hrroi y,[004000,,"C]; [ESCAPE]C
ttyset y, ; clear the screen
ppsel 400002 ; yes, select PP 2 but don't activate yet
outstr hlptxt ; display help text
ppact 100000 ; now activate PP 2
jrst 3(z)] ; and continue
ppact 400000 ; activate PP 0
hrroi y,[004000,,400\"P]; [BREAK]P
ttyset y, ; refresh screen
outstr [asciz/Type any character to return to ITS:/]
inchrw y ; get a character
outstr [asciz/
/]
clrbfi ; flush any other input (like CRLF)
caxn x,"? ; was it a help frob?
pprel 2 ; flush temporary page printer
jrst @review] ; and review screen
caxn x,"R ; screen record crock?
jrst record ; yes, write record file
caxn x,"S ; slow mode?
jrst [ store %fword,slowip ; yes
outstr [asciz/Slow display mode!
/]
jrst ttiser] ; and continue gobbling input
caxn x,"V ; re-view screen?
review: jrst [ leypos 2000 ; line editor off screen
ppact ; flush all PP's
skipe dmp ; is this a DM?
call dmredw ; redraw the whole screen
store %fword,saupdp ; must redisplay whole screen
call scnupd ; update screen
store %zeros,ntoinp ; clear output resets
jrst ttiser] ; all done
; (continued on next page)
; Esoteric character mappings (all magical)
caxe y,%txctl\"z ; αz or αβz?
caxn y,%txctl\"Z ; αZ or αβZ?
jrst imgsnd ; yes, send it in image form
caxn y,%txctl\"_ ; α_ or αβ_?
jrst [ addx x,"←-"_ ; map it first
jrst imgsnd] ; and send it
txz y,%txctl ; flush αification
caxn y,". ; centered-dot?
jrst [ addx x,%txtop-". ; yes
jrst imgsnd] ; and send it
caxe y,↑I ; gamma?
caxn y,↑J ; delta?
jrst [addx x,%txtop ; yes
jrst imgsnd] ; and send it
caxe y,↑M ; circle-plus?
caxn y,177 ; integral?
jrst [addx x,%txtop ; yes
jrst imgsnd] ; and send it
caxn y,"∂ ; [NULL]?
jrst [ subx x,"∂ ; yes
jrst imgsnd] ; and send it
caxe y,"λ ; λ? [BACK SPACE]
caxn y,"∨ ; ∨? [BACK NEXT]
jrst imgsnd ; yes, send it
caxn y,"≠ ; ≠? [CALL]
jrst [ subx x,"≠-"~ ; yes, convertify (cretin character set)
jrst imgsnd] ; yes, send it
caxn y,"α ; α? [ESCAPE]
jrst [ addx x,%txtop\<"A-"α> ; yes, change α to [ESCAPE]
jrst imgsnd] ; and send it
caxn y,"β ; β? [BREAK]
jrst [ addx x,%txtop\<"B-"β> ; yes, change β to [BREAK]
jrst imgsnd] ; and send it
caxn y,"ε ; ε? [CLEAR]
jrst [ addx x,%txtop\<"C-"ε> ; yes, change ε to [CLEAR]
jrst imgsnd] ; and send it
caxn y,"↑ ; ↑? uparrow
jrst [ addx x,%txtop+013-"↑ ; yes, change ↑ to uparrow
jrst imgsnd] ; and send it
; (continued on next page)
; Magic DDT command, subroutines, etc.
prtcmd: caxn x,"? ; want help?
jrst [ outstr hlptx1 ; yes
jrst ttiser] ; now get characters
caxn x,"D ; enter DDT | RAID?
jrst [ call ddtcal ; call DDT
jrst ttiser] ; return from DDT, return to user
skipe prtp ; printing console?
jrst [ andx x,37 ; yes, make character a control
jrst imgsnd] ; and send it
; If not a command or a magical character, burp
outchr ["'] ; quote it
outchr x ; output the loser
burp [asciz/' is an illegal command character.
/]
movx x,%fword ; to myself
beep x, ; breedle!
jrst ttiser ; now continue
imgsnd: store %fword,imgchp ; image characters now
call netoch ; send it too
call netsnd ; send it out
jrst ttiser ; and try for another
; SUPDUP help text
hlptxt: asciz/Commands:
F New fast display mode H Send [HELP] ("help" key)
K or L Kill job and quit P View page printer
Q Detach job and quit R Write a screen record
S Old slow display mode V Re-draw screen
? Type this message
Special mappings:
. centered-dot [TAB] gamma [LF] delta
[CR] circle-plus [BS] integral ⊗ [NULL]
λ [BACK SPACE] ≠ [CALL] ∨ [BACK NEXT]
α [ESCAPE] β [BREAK] ε [CLEAR]
↑, α↑, β↑, αβ↑, αz, αβz, αZ, αβZ, α_, and αβ_ are not mapped in command mode.
/
hlptx1: asciz/
Commands:
K or L Kill job and quit Q Detach job and quit
? Type this message
Any other character is controllified and sent.
/
subttl Screen record crock
record: open dsk,[0 ? 'DSK,, ? dsobf,,] ; get a disk channel
barf [asciz/Unable to OPEN the DSK!
/]
hrroi x,[004000,,400\"N] ; [BREAK]N
ttyset x, ; normalize screen
ptjobx [0 ? sixbit/DON/] ; turn echoing on
movx x,%fword ; this terminal
getlin x ; get line characteristics
txz x,spcbrk ; special activation mode bit
setlin x ; leave SAM
setact [[777777,,777777 ; activate on 000 - 043
777700,,037600 ; 044 - 107
000000,,374000 ; 110 - 153
000007,,600000]] ; 154 - 177
outstr [asciz/Writing screen record.../]
movx x,<-nlines,,> ; number of lines to write
recrd1: movx y,nwrdln ; number of words to offset
imuli y,(x) ; compute offset from start of screen
add y,[440700,,screen+1] ; absolute address of line's characters-1
recrd2: ildb z,y ; get a character from the line
jumpe z,recrd2 ; bop away nulls
sosg dsobf+2 ; any room in the buffer?
out dsk, ; no, dump out what's there now
caxa ; won
barf [asciz/Disk OUT failed!
/]
idpb z,dsobf+1 ; save character
caxe z,↑J ; hit the line feed yet?
jrst recrd2 ; not yet
aobjn x,recrd1 ; won
close dsk, ; close off file
release dsk, ; free up channel
ptjobx [0 ? sixbit/DOFF/] ; turn echoing off
movx x,%fword ; this line
getlin x ; get line characteristics
txo x,spcbrk ; special activation mode bit
setlin x ; enter SAM
setact [[777777,,777777 ; activate on 000 - 043
777777,,777777 ; 044 - 107
777777,,777777 ; 110 - 153
777777,,600000\allact\bsact\supscm\supccr]]; 154 - 177, αβ act
ppact ; flush PP 0
jrst @review ; and redraw screen
subttl Network error analysis
; Connection refused
refuse: outstr [asciz/Refused./]
exit
; Connection closed by foreign host
closed: outstr [asciz/Host closed connection./]
exit
; Failed to get socket number from logger
nosock: getsts icp,y ; get channel status of loser
jrst iioerr ; and report why it happened
; CONNECT MTAPE error codes
define cnemes code,message/
ifn 1+.-cnetab-code,.err code is out of order
[asciz/message/]
termin
cnetab: cnemes siu,Socket already in use.
cnemes ccs,Can't change socket numbers.
cnemes sys,Horrible system error.
cnemes nla,No links available.
cnemes ilb,Illegal byte size.
cnemes idd,Local NCP dead.
cnemax==1+.-cnetab
; CONNECT MTAPE failed
conerr: andx x,77 ; only error code
caxl x,cnemax ; error code too high?
jrst [ outstr [asciz/Connection failed, code #/]
idivx x,10 ; split into two digits
repeat 2,[
addx x+.rpcnt,"0 ; ASCIIify
outchr x+.rpcnt ; output the digit
] ; once for each digit
outchr [".] ; final dot
exit] ; and die
outstr @cnetab-1(x) ; output error message
exit ; and exit
; More network error reporting
; IMP I/O error
nioerr: getsts net,y ; get error status
skipe clsedp ; known that it was closing?
jrst closed ; okay, report that instead
iioerr: andx y,ioimpm\ioderr\iodter\iobktl\iodend\hdead\ctrov\rset\tmo
txzn y,hdead
jrst cctrov
txz y,ioderr\iodter ; clear other error bits
outstr [asciz/Host dead./]
jumpe y,[exit] ; punt if done
outstr [asciz/
/]
cctrov: txnn y,ctrov
jrst crset
txz y,ioderr\iodter ; clear other error bits
outstr [asciz/Host exceeded allocation./]
jumpe y,[exit] ; punt if done
outstr [asciz/
/]
crset: txnn y,rset
jrst ctmo
txz y,ioderr\iodter ; clear other error bits
outstr [asciz/Host reset./]
jumpe y,[exit] ; punt if done
outstr [asciz/
/]
ctmo: txnn y,tmo
jrst ceof
txz y,ioderr\iodter ; clear other error bits
outstr [asciz/Time out./]
jumpe y,[exit] ; punt if done
outstr [asciz/
/]
ceof: txnn y,iodend
jrst cbktl
txz y,ioderr\iodter ; clear other error bits
outstr [asciz/End of file./]
jumpe y,[exit] ; punt if done
outstr [asciz/
/]
cbktl: txne y,iobktl\ioimpm ; argh!!!
barf [asciz/IOIMPM or IOBKTL!
Find a wizard./]
; Occasionally IODTER and IODERR get set with nothing else.
txze y,iodter ; for this bit or the other
txo y,ioderr ; or both
caxn y,ioderr ; for when only this bit is set
outstr [asciz/Incomplete transmission./]
exit ; and die
subttl Random routines, literals, etc.
; Here if could not get terminal name; give a random string
rndtid: burp [asciz/Unable to get terminal's location from ROOMS[P,DOC].
/]
move y,[440700,,[asciz/Unknown Data Disc/]]
skipe iiip ; is it a III?
move y,[440700,,[asciz/Unknown III/]]
skipe prtp ; printing console?
move y,[440700,,[asciz/Unknown TTY/]]
skipn dmp ; is it a DM?
jrst sndid1 ; no
skipa y,[440700,,[asciz/Unknown Datamedia/]]
rndrom: move y,[440700,,[asciz/Unassigned Room/]]
sndid1: ildb x,y ; get a character
call netoc1 ; send it
jumpn x,sndid1 ; and continue if not done
jrst tidone ; all done
; Here to get a character from terminal rooms table
getch: sosg dsibf+2 ; buffer ready?
in dsk, ; no, get one then
caxa ; won
jrst rndtid ; lost, send random name
ildb x,dsibf+1 ; get a character
jumpe x,getch+1 ; flush nulls
caxe x,↑M ; hit a terpri?
cpopj1: aos (p) ; no, bump return PC
return ; now return
; For handling REENTER command
tmploc jobren,rensvr ; re-entry point
rensvr: skipe jobopc ; was I interrupted?
jrst 2,@jobopc ; yup, then continue
jrst supdup ; no, just start then
; Literals
...lit: variables ; don't like variables!
if1,ifn .-...lit,.err Variables lose lose lose
constants ; generate constants
sdpff=. ; first free location in SUPDUP
end SUPDUP